<?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=Vkdodiya</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=Vkdodiya"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Vkdodiya"/>
	<updated>2026-08-19T18:10:08Z</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_-_E2531_Refactor_participants_controller.rb&amp;diff=165287</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=165287"/>
		<updated>2025-04-27T20:00:28Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Methods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
==Video Overview==&lt;br /&gt;
&lt;br /&gt;
https://youtu.be/4kfz0hrmSg4&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; In the video it shows the test file at the end, but does not mention a last-minute change that numbers all of the tests to make it much easier to keep track of each of the tests and which ones are passing.&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Use of Large Language Models (LLMs)=&lt;br /&gt;
&lt;br /&gt;
For this project, we are using ChatGPT as an LLM helper in determining what issues there are within the code. The use of LLMs in this project will likely be limited to probing for potential issues that exist within the system.&lt;br /&gt;
&lt;br /&gt;
Below we have organized the following prompts and a summary of the output in a table:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 25%&amp;quot; | Prompts !! LLM Output Summary&lt;br /&gt;
|-&lt;br /&gt;
| [Code from &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;]&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt; Are there any ways where we can refactor the code to improve readability, DRYness, and clarity of error handling?&lt;br /&gt;
|| It recognized some of the issues we, as a team, had already identified and suggested fixes that were similar to what we outlined: &amp;lt;b&amp;gt;Redundant JSON Rendering Code&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_Redundant_JSON_Rendering_Code] and &amp;lt;b&amp;gt;Simplifying the Assignment of Participant Fields&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_the_Assignment_of_Participant_Fields]. Additionally, it suggested minor changes that we could implement, such as using &amp;lt;code&amp;gt;Participant.where(...)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; to filter out the code more efficiently instead of getting all database instances every time, as well as the use of strong parameters in &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update_authorization()&amp;lt;/code&amp;gt; to avoid having to implement custom parsing techniques. It also recommends renaming the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; function to something more specific in relation to its purpose (adding a &amp;lt;code&amp;gt;Participant&amp;lt;/code&amp;gt; to an &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Potential Redundant Tests in &amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|| The tests on line 222 and 231 are redundant as only the authorization differs. (Note: This should be investigated to see whether or not this is necessary)&lt;br /&gt;
|-&lt;br /&gt;
| Checking for issues with the current testing files&lt;br /&gt;
|| The &amp;quot;Get Participant by ID call&amp;quot; test was returning a 201 status code instead of the more suitable 200 code&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed information on what prompts we used and the output we got, please visit the page here: [https://docs.google.com/document/d/105_U_Coky-edx7n-tFhD2B5RqmVXxEsKPW_qUaf7bQU/edit?usp=sharing].&lt;br /&gt;
&lt;br /&gt;
=Requirements=&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Some API functions are not returning the correct HTML status messages (e.g. test on line 136 returns 201 instead of 200)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Documentation and comments can be somewhat vague&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;In-line comments should be more descriptive, explaining what the code does in more details&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Tests are not described via comments, but in name alone; some more descriptive comments that explain the tests in more detail would be ideal&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Design / Proposed Solution=&lt;br /&gt;
&lt;br /&gt;
Based on the previous implementation's controller diagram, we have created a new version that contains our proposed changes and modifications to &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[File:Participants_controller_refactor_v1.2.png]]&lt;br /&gt;
&lt;br /&gt;
==Simplifying Redundant JSON Rendering Code==&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Simplifying the Assignment of Participant Fields==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update()&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Provide More Clarity in Function Names==&lt;br /&gt;
&lt;br /&gt;
There are some functions that are somewhat unclear/vague in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. For example, the &amp;lt;code&amp;gt;list_user_participants()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== - Suggested Method Name Improvements ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Old Method Name&lt;br /&gt;
! New Method Name&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Clearer and more descriptive&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Clearer and more descriptive and is consistent with the other get method&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;&lt;br /&gt;
| Describes both creation and authorization setup of participant to assignment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_user_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt;&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_assignment_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Improve Documentation and Comments==&lt;br /&gt;
&lt;br /&gt;
Some of the documentation and in-line comments can be somewhat vague. This can lead to misconceptions about how some functions work or how some of the code can function. Below are potential improvements we plan to make for function descriptions, though these may change with the final implementation.&lt;br /&gt;
&lt;br /&gt;
=== Improved Method Comments ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Original Comment&lt;br /&gt;
! Refactored Comment&lt;br /&gt;
|-&lt;br /&gt;
| render_participants_by_user_id&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
| Retrieves all participants associated with the specified user ID&lt;br /&gt;
|-&lt;br /&gt;
| render_participants_by_assignment_id&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
| Retrieves all participants linked to the specified assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
| Fetch and return the participant with the given ID&lt;br /&gt;
|-&lt;br /&gt;
| add_participant_to_assignment&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
| Creates a new participant for a given assignment and assigns appropriate authorization and permissions&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
| Updates the participant’s authorization role and related permissions&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
| Deletes the participant identified by the given ID and returns a confirmation message&lt;br /&gt;
|-&lt;br /&gt;
| participant_params&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
| Strong parameters: list of attributes allowed for participant creation or update&lt;br /&gt;
|-&lt;br /&gt;
| filter_participants_by_user&lt;br /&gt;
| Filters participants based on the provided user. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by user, if provided&lt;br /&gt;
|-&lt;br /&gt;
| filter_participants_by_assignment&lt;br /&gt;
| Filters participants based on the provided assignment. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by assignment, if provided&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| Validates that the authorization parameter is present and is one of the following valid authorizations: reader, reviewer, submitter, mentor&lt;br /&gt;
| Ensures authorization param is valid and returns it in lowercase; otherwise returns error response&lt;br /&gt;
|-&lt;br /&gt;
| find_user / find_assignment / find_participant&lt;br /&gt;
| Finds a user/assignment/participant by ID and returns it&lt;br /&gt;
| Fetches the corresponding record by ID; renders a not-found error if record does not exist&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Proposed Testing Changes==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add more descriptive comments for tests&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that authorizations are updated correctly&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that inputted path parameters are not missing and valid inputs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Tests at Line 222 and Line 231 are redundant, as the only difference in the test is the authorization, which would not affect what happens if a participant is not found&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
As this is a refactoring project, most of our work on the codebase involved cleaning up the current codebase to better align with foundational code style principles rather than introducing any of kind of new functionality. Our primary focus is to make the code more readable and easier to work with than before. We also took the liberty of fixing some minor errors that we found along the way.&lt;br /&gt;
&lt;br /&gt;
==Changelog==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Naming changes to multiple functions for better clarity and consistency&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Changed HTML status message for &amp;lt;code&amp;gt;show()&amp;lt;/code&amp;gt; from 201 (Created) to 200 (OK) as it is a better fit&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Created the &amp;lt;code&amp;gt;assign_participant_permissions()&amp;lt;/code&amp;gt; method&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Introduced two additional tests and removed a redundant one (see Testing Plan for more details)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Removed redundant queries to &amp;lt;code&amp;gt;Participant.all()&amp;lt;/code&amp;gt; in both filtering methods&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Updated method comments to be more descriptive (see comments table in Design)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Function Name Changes==&lt;br /&gt;
&lt;br /&gt;
The previous implementation had several functions that were strangely named or had names that could be easily misconstrued. The name changes remain the same from the proposal and design section, but for the purpose of clarity, the rationale for each of the functions will be provided below.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
These two functions are meant to render a list of participants given a &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt; respectively. Based on the name alone, it is difficult to tell that the function would render a User/Assignment or Participants. In order to remedy this, we chose the names &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;. The word &amp;quot;list&amp;quot; was replaced by &amp;quot;render&amp;quot; in order to better denote that it is rendering something (json in this case) and the &amp;quot;by&amp;quot; is added to emphasize that the User and Assignment are being used as parameters to search for the Participants. This provides a much clearer picture of what these functions should do compared to before.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; function's name was too vague to be particularly useful in identifying its purpose. To be more accurate, the function was meant to add the user to a given assignment, which would return a participant from the assignment's &amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; function. The new name of the function provides much more context to what it does (&amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_user_participants&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_assignment_participants&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Similar to the list methods that were previously mentioned, it is difficult to tell what exactly these two functions do. While it can be easily seen that it filters something, what is being filtered can be easily mistaken (e.g. does it filter users by participants or participants by users?). The new names, &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt; are much clearer in defining that the User and Assignment are being used as the filter parameters for the function.&lt;br /&gt;
&lt;br /&gt;
==HTML Status Code Change for &amp;lt;code&amp;gt;GET&amp;lt;/code&amp;gt; Call==&lt;br /&gt;
&lt;br /&gt;
The status code being used for this was previously 201, denoting &amp;quot;successful creation&amp;quot;. We have corrected this to a simple 200 code, which signifies an &amp;quot;ok&amp;quot; status message. This issue was actually identified by ChatGPT while we were dowsing for potential issues.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Test modified&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# Tests whether a participant returns properly if provided with a valid Participant ID&lt;br /&gt;
response '200', 'Returns a participant' do&lt;br /&gt;
  let(:id) { participant2.id }&lt;br /&gt;
&lt;br /&gt;
  run_test! do |response|&lt;br /&gt;
    data = JSON.parse(response.body)&lt;br /&gt;
    expect(data['user_id']).to eq(studenta.id)&lt;br /&gt;
    expect(data['assignment_id']).to eq(assignment2.id)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Redundant &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; Queries Removed==&lt;br /&gt;
&lt;br /&gt;
This issue was initially caught by the LLM, ChatGPT, that the team was using in order to find potential issues. We found that simply using &amp;lt;code&amp;gt;Participant.where()&amp;lt;/code&amp;gt; removed the need for the &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; query entirely while changing nothing else about the function, reducing the amount of queries necessary to call the filtering methods, &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# New function&lt;br /&gt;
def filter_participants_by_user(user)&lt;br /&gt;
  participants = Participant.where(user_id: user.id) if user # This would simply get the participants given the proper user ID&lt;br /&gt;
  participants.order(:id)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# Old function&lt;br /&gt;
def filter_participants_by_user(user)&lt;br /&gt;
  participants = Participant.all() # This would obtain the entire list of participants rather than just the necessary ones&lt;br /&gt;
  participants = participants.where(user_id: user.id) if user&lt;br /&gt;
  participants.order(:id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==New Private Method: &amp;lt;code&amp;gt;assign_participant_permissions()&amp;lt;/code&amp;gt;==&lt;br /&gt;
&lt;br /&gt;
The reasoning behind the addition of this method is because of a repeated piece of code that existed in the previous implementation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
participant.authorization = authorization&lt;br /&gt;
participant.can_submit = permissions[:can_submit]&lt;br /&gt;
participant.can_review = permissions[:can_review]&lt;br /&gt;
participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This was repeated in two different contexts: when the Participant was updated or created. This is a violation of the DRY principle, as the same code is repeated multiple times where it could have been reduced to make it more easily readable. In order to resolve this issue, we simply turned this code snippet into a private method that can be called within &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  # An authorization string containing the participant's role is taken and used to determine&lt;br /&gt;
  # what permissions will be allocated to the participant. Each of these permissions will&lt;br /&gt;
  # then be assigned to the Participant's database permission attributes.&lt;br /&gt;
  #&lt;br /&gt;
  # @param [String] authorization: An authorization string that represents the participant's role&lt;br /&gt;
  # @param [Participant] participant: The participant whose authorization permissions are being updated&lt;br /&gt;
  def assign_participant_permissions(authorization, participant)&lt;br /&gt;
    # Call helper method from participants_helper to retrieve a dictionary containing the&lt;br /&gt;
    # appropriate permission boolean values for the role specified by the authorization string&lt;br /&gt;
    permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
    # Assigns each of the boolean permission values to their respective database counterparts&lt;br /&gt;
    participant.authorization = authorization&lt;br /&gt;
    participant.can_submit = permissions[:can_submit]&lt;br /&gt;
    participant.can_review = permissions[:can_review]&lt;br /&gt;
    participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
    participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Description:===&lt;br /&gt;
&lt;br /&gt;
An authorization string containing the participant's role is taken and used to determine what permissions will be allocated to the participant. Each of these permissions will then be assigned to the Participant's database permission attributes.&lt;br /&gt;
&lt;br /&gt;
===Parameters:===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt;: An authorization string that represents the participant's role. This can be either reader, reviewer, submitter, or mentor.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant&amp;lt;/code&amp;gt;: The participant whose attributes are being updated. This is passed in to be modified by the function to be used to assign each of the participant's attribute values that are representative of its assigned role.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Behavior===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Use &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;participants_helper&amp;lt;/code&amp;gt; in order to get all necessary permission boolean values for a given participant role&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Assign each of the permission boolean values (&amp;lt;code&amp;gt;can_submit&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_review&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_take_quiz&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_mentor&amp;lt;/code&amp;gt;)&amp;lt;/li&amp;gt; from the helper method to their respective database attribute counterparts in Participant&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Post-Demo Changes==&lt;br /&gt;
&lt;br /&gt;
There were three notable topics that were brought up during the final demo presentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The renaming of &amp;lt;code&amp;gt;get_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;get_participants_by_assignment&amp;lt;/code&amp;gt; to something more suitable to its purpose in rendering the JSON of a list of participants&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Consider the application of &amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; within &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Update the wiki to provide descriptions for each of the methods included in &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt; (See Methods subsection in the Implementation section)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Renaming &amp;lt;code&amp;gt;get_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;get_participants_by_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
These two functions were renamed (once again) to something that better fit the functionality and purpose of the function. Since these functions are meant to render the lists of participants gotten from their respective parameters and use the ID values for each, both of the functions were renamed to &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt; respectively. The renaming of the filter methods was also brought up, but those functions actually do use the objects themselves as parameters, so have been left as is for the time being.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; within &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
We reconsidered the use of these methods within the controller since it was somewhat odd that it would have these methods. However, we concluded that, since the find methods are helper methods that are private and not open to be used by other parts of the code, to be fine to leave as is. This is mostly because they are simple helper methods that get the current user and assignment and return them, rendering an error if they do not exist.&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches all participants associated with the specified user. Primarily used to retrieve the list of participants which are equate to the user ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;user_id [Integer]&amp;lt;/code&amp;gt;: ID of the user&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; A JSON array of participant objects&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized for the action&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If the user does not exist&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If the query fails unexpectedly&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Renamed from &amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def render_participants_by_user_id&lt;br /&gt;
    user = find_user if params[:user_id].present?&lt;br /&gt;
    return if params[:user_id].present? &amp;amp;&amp;amp; user.nil?&lt;br /&gt;
&lt;br /&gt;
    participants = filter_participants_by_user(user)&lt;br /&gt;
&lt;br /&gt;
    if participants.nil?&lt;br /&gt;
      render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participants, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Fetches all participants associated with a specific assignment. Primarily used to retrieve the list of participants enrolled in an assignment for administrative purposes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment_id [Integer]&amp;lt;/code&amp;gt;: ID of the assignment&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; A JSON array of participant objects&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized for the action&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If the assignment does not exist&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If the query fails unexpectedly&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Renamed from &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def render_participants_by_assignment_id&lt;br /&gt;
    assignment = find_assignment if params[:assignment_id].present?&lt;br /&gt;
    return if params[:assignment_id].present? &amp;amp;&amp;amp; assignment.nil?&lt;br /&gt;
&lt;br /&gt;
    participants = filter_participants_by_assignment(assignment)&lt;br /&gt;
&lt;br /&gt;
    if participants.nil?&lt;br /&gt;
      render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participants, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;show&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches the details of a specific participant by their ID. Provides all attributes related to the participant, useful for detailed user tracking.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; JSON representation of the participant&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If the participant does not exist&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If the lookup fails&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Standardized participant lookup to return proper HTTP codes&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def show&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if participant.nil?&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adds a user as a participant to an assignment with the specified authorization (role and permissions). This method ensures that appropriate permission settings are applied based on the participant's assigned role.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant[user_id] [Integer]&amp;lt;/code&amp;gt;: ID of the user&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant[assignment_id] [Integer]&amp;lt;/code&amp;gt;: ID of the assignment&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: Role assigned to the participant (reader, reviewer, submitter, mentor)&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;201 Created:&amp;lt;/b&amp;gt; Participant successfully added&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If user or assignment is not found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If authorization is invalid or save fails&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;The naming convention was made similar to other methods&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def add_participant_to_assignment&lt;br /&gt;
    user = find_user&lt;br /&gt;
    return unless user&lt;br /&gt;
&lt;br /&gt;
    assignment = find_assignment&lt;br /&gt;
    return unless assignment&lt;br /&gt;
&lt;br /&gt;
    authorization = validate_authorization&lt;br /&gt;
    return unless authorization&lt;br /&gt;
&lt;br /&gt;
    participant = assignment.add_participant(user)&lt;br /&gt;
    assign_participant_permissions(authorization, participant)&lt;br /&gt;
&lt;br /&gt;
    if participant.save&lt;br /&gt;
      render json: participant, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;update_authorization&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Updates the authorization (role) of an existing participant. Used when a participant's responsibilities or privileges within an assignment change and need to be updated.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: New role to assign (reader, reviewer, submitter, mentor)&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;201 Created:&amp;lt;/b&amp;gt; Authorization updated successfully&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If participant is not found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If authorization is invalid&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Added validation for authorization role values&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = find_participant&lt;br /&gt;
    return unless participant&lt;br /&gt;
&lt;br /&gt;
    authorization = validate_authorization&lt;br /&gt;
    return unless authorization&lt;br /&gt;
&lt;br /&gt;
    assign_participant_permissions(authorization, participant)&lt;br /&gt;
&lt;br /&gt;
    if participant.save&lt;br /&gt;
      render json: participant, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;destroy&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deletes a participant from the system. Optionally includes assignment and team context in the success message. This helps maintain clean records by removing users who drop out or are mistakenly added.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment_id [Integer] (optional)&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;team_id [Integer] (optional)&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; Success message indicating deletion&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If participant is not found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If deletion fails&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Enhanced success message based on team/assignment presence&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def destroy&lt;br /&gt;
    participant = Participant.find_by(id: params[:id])&lt;br /&gt;
  &lt;br /&gt;
    if participant.nil?&lt;br /&gt;
      render json: { error: 'Not Found' }, status: :not_found&lt;br /&gt;
    elsif participant.destroy&lt;br /&gt;
      successful_deletion_message = if params[:team_id].nil?&lt;br /&gt;
                                      &amp;quot;Participant #{params[:id]} in Assignment #{params[:assignment_id]} has been deleted successfully!&amp;quot;&lt;br /&gt;
                                    else&lt;br /&gt;
                                      &amp;quot;Participant #{params[:id]} in Team #{params[:team_id]} of Assignment #{params[:assignment_id]} has been deleted successfully!&amp;quot;&lt;br /&gt;
                                    end&lt;br /&gt;
      render json: { message: successful_deletion_message }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;participants_params&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Defines the strong parameters allowed when creating or updating a participant. Ensures only permitted and validated fields are processed to protect against malicious data injection.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant&amp;lt;/code&amp;gt;: Hash containing fields like user_id, assignment_id, authorization, etc.&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Permitted parameter hash for participant creation/update&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Updated to include all permission and assignment-related fields&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def participant_params&lt;br /&gt;
    params.require(:participant).permit(:user_id, :assignment_id, :authorization, :can_submit,&lt;br /&gt;
                                        :can_review, :can_take_quiz, :can_mentor, :handle,&lt;br /&gt;
                                        :team_id, :join_team_request_id, :permission_granted,&lt;br /&gt;
                                        :topic, :current_stage, :stage_deadline)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches participants associated with a given user, ordered by ID. Primarily used when displaying all participations of a single user across different assignments.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;user [User]&amp;lt;/code&amp;gt;: User object&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Ordered list of participants for the user&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def filter_participants_by_user(user)&lt;br /&gt;
    participants = Participant.where(user_id: user.id) if user&lt;br /&gt;
    participants.order(:id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches participants associated with a given assignment, ordered by ID. Helps instructors or admins manage the list of all users participating in a particular assignment.&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment [Assignment]&amp;lt;/code&amp;gt;: Assignment object&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Ordered list of participants for the assignment&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def filter_participants_by_assignment(assignment)&lt;br /&gt;
    participants = Participant.where(assignment_id: assignment.id) if assignment&lt;br /&gt;
    participants.order(:id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finds a user based on the provided user_id. Validates the existence of the user before performing operations like adding or retrieving participants&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;user_id [Integer]&amp;lt;/code&amp;gt;: ID of the user&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;User object if found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;404 error if not found&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Centralized user lookup and error handling&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_user&lt;br /&gt;
    user_id = params[:user_id]&lt;br /&gt;
    user = User.find_by(id: user_id)&lt;br /&gt;
    render json: { error: 'User not found' }, status: :not_found unless user&lt;br /&gt;
    user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finds an assignment based on the provided assignment_id. Ensures that participant-related actions are linked to a valid and existing assignment record.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment_id [Integer]&amp;lt;/code&amp;gt;: ID of the assignment&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Assignment object if found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;404 error if not found&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Centralized assignment lookup and error handling&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_assignment&lt;br /&gt;
    assignment_id = params[:assignment_id]&lt;br /&gt;
    assignment = Assignment.find_by(id: assignment_id)&lt;br /&gt;
    render json: { error: 'Assignment not found' }, status: :not_found unless assignment&lt;br /&gt;
    assignment&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&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;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finds a participant based on the provided ID. Used internally to validate the participant’s presence before operations like update, show, or delete.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Participant object if found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;404 error if not found&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Centralized participant lookup and error handling&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_participant&lt;br /&gt;
    participant_id = params[:id]&lt;br /&gt;
    participant = Participant.find_by(id: participant_id)&lt;br /&gt;
    render json: { error: 'Participant not found' }, status: :not_found unless participant&lt;br /&gt;
    participant&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;assign_participant_permissions&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Assigns permission flags to a participant based on the authorization role provided. It automatically maps permissions like can_submit, can_review, can_take_quiz, and can_mentor depending on the assigned role.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: Role to assign&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant [Participant]&amp;lt;/code&amp;gt;: Participant object&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Participant object with updated permissions&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Added dynamic permission setting based on role&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def assign_participant_permissions(authorization, participant)&lt;br /&gt;
    # Call helper method from participants_helper to retrieve a dictionary containing the&lt;br /&gt;
    # appropriate permission boolean values for the role specified by the authorization string&lt;br /&gt;
    permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
    # Assigns each of the boolean permission values to their respective database counterparts&lt;br /&gt;
    participant.authorization = authorization&lt;br /&gt;
    participant.can_submit = permissions[:can_submit]&lt;br /&gt;
    participant.can_review = permissions[:can_review]&lt;br /&gt;
    participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
    participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;validate_authorization&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Validates that the authorization string is present and one of the accepted roles. Ensures role-based access integrity by allowing only predefined, valid roles to be assigned to participants.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: Authorization role&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Validated authorization string&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;422 error if invalid&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Standardized authorization validation across endpoints&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def validate_authorization&lt;br /&gt;
    valid_authorizations = %w[reader reviewer submitter mentor]&lt;br /&gt;
    authorization = params[:authorization]&lt;br /&gt;
    authorization = authorization.downcase if authorization.present?&lt;br /&gt;
&lt;br /&gt;
    unless authorization&lt;br /&gt;
      render json: { error: 'authorization is required' }, status: :unprocessable_entity&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    unless valid_authorizations.include?(authorization)&lt;br /&gt;
      render json: { error: 'authorization not valid. Valid authorizations are: Reader, Reviewer, Submitter, Mentor' },&lt;br /&gt;
             status: :unprocessable_entity&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    authorization&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Testing Plan=&lt;br /&gt;
&lt;br /&gt;
Of this implementation, also existing 25 tests are passing. We have also given each test their respective IDs within &amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt; as well so that they may be more easily identifiable. For more information about the previous testing plan, please refer to the previous implementation's page here: [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2484._Reimplement_participants_controller.rb]&lt;br /&gt;
&lt;br /&gt;
Below are any modifications to the existing test file (&amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt;) that we have made during the course of this project, alongside the descriptions and rationales behind them:&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
Below are the tests that are included in this implementation. We have updated the test descriptions to include more accurate and detailed information about each of the tests as well. Any tests that have been modified or new will be specified as such:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Retrieve participants by valid user ID (should return participant data)&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Retrieve participants by user ID with no participants (should return empty array)&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Retrieve participants with non-existent user ID (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Retrieve participants by user ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Retrieve participants by valid assignment ID (should return participant data)&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Retrieve participants by non-existent assignment ID (should return 'Assignment not found')&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Retrieve participants by assignment ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Retrieve a participant by valid ID (should return participant details)&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Retrieve a participant by non-existent ID (should return 'Not Found')&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Retrieve a participant by ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Delete a participant by valid ID (should return deletion success message)&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Delete a participant by non-existent ID (should return 'Not Found')&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Delete a participant by ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Update participant authorization with valid data (should return updated authorization)&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Update participant authorization with non-existent participant ID (should return 'Participant not found')&lt;br /&gt;
|-&lt;br /&gt;
| 16 || Update participant authorization with invalid role (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 17 || Update participant authorization with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 18 || Add a participant successfully (should return participant data with authorization)&lt;br /&gt;
|-&lt;br /&gt;
| 19 || Add a participant that already exists (should return duplicate participant error)&lt;br /&gt;
|-&lt;br /&gt;
| 20 || Add a participant with non-existent user ID (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 21 || Add a participant with non-existent assignment ID (should return 'Assignment not found')&lt;br /&gt;
|-&lt;br /&gt;
| 22 || Add a participant with invalid authorization (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 23 || Add a participant with unsupported authorization format (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 24 (NEW) || Add a participant missing user_id in request body (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 25 (NEW) || Add a participant missing assignment_id in request body (should return 'Assignment not found')&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Removed Tests==&lt;br /&gt;
&lt;br /&gt;
These are any tests that we have modified or removed from the previous testing plan. If the test ID is denoted by (Previously), that means that the ID shown was part of the previous implementation's testing plan.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Modification Description &lt;br /&gt;
|-&lt;br /&gt;
| (Previously) 22 || This test was removed as it was redundant. While it is important to check the authorization of the participant that would be invalid, the invalid ID used for this test is a duplicate of the previous test, meaning the result is guaranteed to match that of the previous test regardless of what is meant to be tested.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Next Steps=&lt;br /&gt;
&lt;br /&gt;
Being able to implement this could potentially simplify rendering to the view somewhat in that it could handle simple HTML status code handling. Below are some examples of implementations to serve as a point of reference:&lt;br /&gt;
&lt;br /&gt;
===Example 1===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# Checks if a target object (participant or participants) is not nil and then renders the object.&lt;br /&gt;
# If the object is nil, renders the object errors and sends a not_found_status and if the object&lt;br /&gt;
# exists, renders the object and sends a success status&lt;br /&gt;
# not_found_status default: :unprocessable_entity (422)&lt;br /&gt;
# success_status default: :ok (200)&lt;br /&gt;
def render_object_or_error(object, not_found_status: :unprocessable_entity, success_status: :ok)&lt;br /&gt;
  if object.nil?&lt;br /&gt;
    render json: { error: 'Resource not found' }, status: not_found_status&lt;br /&gt;
  elsif object.respond_to?(:errors) &amp;amp;&amp;amp; object.errors.any?&lt;br /&gt;
    render json: object.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: object, status: success_status&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example is modeled to be specific to the most common use case for this function in the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; by returning the default 422 and 200 error and success codes that are used by three instances of JSON rendering where it checks for whether a list of participants or a single participant is nil. These default values for the status codes are mainly to cover those instances, but could be changed to something else if necessary. The &amp;lt;code&amp;gt;object&amp;lt;/code&amp;gt; parameter is representative of the object that was meant to be rendered given the success or failure of the operation.&lt;br /&gt;
&lt;br /&gt;
===Example 2===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
def render_object_if(conditional, object, error_status, success_status)&lt;br /&gt;
  if conditional&lt;br /&gt;
    render json: { error: 'Resource not found' }, status: error_status&lt;br /&gt;
  else&lt;br /&gt;
    render json: object, status: success_status&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example is a more generic implementation of the function, mandating the error and success status codes rather than providing default values. The point of this was to emphasize readability when glancing over the use of this function. For example, being able to tell that seeing the function being used would immediately tell the reader what the success and failure states were immediately without having to find and inspect the function itself. The &amp;lt;code&amp;gt;conditional&amp;lt;/code&amp;gt; parameter would also allow the function to act similarly to a more readable ternary statement made for rendering.&lt;br /&gt;
&lt;br /&gt;
Implementing this successfully would reduce the amount of repetitive code being used within the controller, as the if-else view rendering is very common in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. We were unable to implement it within our given timeframe, so we opted to divert our focus on other, important tasks that we needed to do.&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Relevant Links =&lt;br /&gt;
&lt;br /&gt;
Pull Request [https://github.com/expertiza/reimplementation-back-end/pull/192] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=165286</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=165286"/>
		<updated>2025-04-27T19:43:36Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* add_participant_to_assignment */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
==Video Overview==&lt;br /&gt;
&lt;br /&gt;
https://youtu.be/4kfz0hrmSg4&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; In the video it shows the test file at the end, but does not mention a last-minute change that numbers all of the tests to make it much easier to keep track of each of the tests and which ones are passing.&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Use of Large Language Models (LLMs)=&lt;br /&gt;
&lt;br /&gt;
For this project, we are using ChatGPT as an LLM helper in determining what issues there are within the code. The use of LLMs in this project will likely be limited to probing for potential issues that exist within the system.&lt;br /&gt;
&lt;br /&gt;
Below we have organized the following prompts and a summary of the output in a table:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 25%&amp;quot; | Prompts !! LLM Output Summary&lt;br /&gt;
|-&lt;br /&gt;
| [Code from &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;]&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt; Are there any ways where we can refactor the code to improve readability, DRYness, and clarity of error handling?&lt;br /&gt;
|| It recognized some of the issues we, as a team, had already identified and suggested fixes that were similar to what we outlined: &amp;lt;b&amp;gt;Redundant JSON Rendering Code&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_Redundant_JSON_Rendering_Code] and &amp;lt;b&amp;gt;Simplifying the Assignment of Participant Fields&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_the_Assignment_of_Participant_Fields]. Additionally, it suggested minor changes that we could implement, such as using &amp;lt;code&amp;gt;Participant.where(...)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; to filter out the code more efficiently instead of getting all database instances every time, as well as the use of strong parameters in &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update_authorization()&amp;lt;/code&amp;gt; to avoid having to implement custom parsing techniques. It also recommends renaming the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; function to something more specific in relation to its purpose (adding a &amp;lt;code&amp;gt;Participant&amp;lt;/code&amp;gt; to an &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Potential Redundant Tests in &amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|| The tests on line 222 and 231 are redundant as only the authorization differs. (Note: This should be investigated to see whether or not this is necessary)&lt;br /&gt;
|-&lt;br /&gt;
| Checking for issues with the current testing files&lt;br /&gt;
|| The &amp;quot;Get Participant by ID call&amp;quot; test was returning a 201 status code instead of the more suitable 200 code&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed information on what prompts we used and the output we got, please visit the page here: [https://docs.google.com/document/d/105_U_Coky-edx7n-tFhD2B5RqmVXxEsKPW_qUaf7bQU/edit?usp=sharing].&lt;br /&gt;
&lt;br /&gt;
=Requirements=&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Some API functions are not returning the correct HTML status messages (e.g. test on line 136 returns 201 instead of 200)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Documentation and comments can be somewhat vague&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;In-line comments should be more descriptive, explaining what the code does in more details&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Tests are not described via comments, but in name alone; some more descriptive comments that explain the tests in more detail would be ideal&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Design / Proposed Solution=&lt;br /&gt;
&lt;br /&gt;
Based on the previous implementation's controller diagram, we have created a new version that contains our proposed changes and modifications to &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[File:Participants_controller_refactor_v1.2.png]]&lt;br /&gt;
&lt;br /&gt;
==Simplifying Redundant JSON Rendering Code==&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Simplifying the Assignment of Participant Fields==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update()&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Provide More Clarity in Function Names==&lt;br /&gt;
&lt;br /&gt;
There are some functions that are somewhat unclear/vague in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. For example, the &amp;lt;code&amp;gt;list_user_participants()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== - Suggested Method Name Improvements ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Old Method Name&lt;br /&gt;
! New Method Name&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Clearer and more descriptive&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Clearer and more descriptive and is consistent with the other get method&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;&lt;br /&gt;
| Describes both creation and authorization setup of participant to assignment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_user_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt;&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_assignment_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Improve Documentation and Comments==&lt;br /&gt;
&lt;br /&gt;
Some of the documentation and in-line comments can be somewhat vague. This can lead to misconceptions about how some functions work or how some of the code can function. Below are potential improvements we plan to make for function descriptions, though these may change with the final implementation.&lt;br /&gt;
&lt;br /&gt;
=== Improved Method Comments ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Original Comment&lt;br /&gt;
! Refactored Comment&lt;br /&gt;
|-&lt;br /&gt;
| render_participants_by_user_id&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
| Retrieves all participants associated with the specified user ID&lt;br /&gt;
|-&lt;br /&gt;
| render_participants_by_assignment_id&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
| Retrieves all participants linked to the specified assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
| Fetch and return the participant with the given ID&lt;br /&gt;
|-&lt;br /&gt;
| add_participant_to_assignment&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
| Creates a new participant for a given assignment and assigns appropriate authorization and permissions&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
| Updates the participant’s authorization role and related permissions&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
| Deletes the participant identified by the given ID and returns a confirmation message&lt;br /&gt;
|-&lt;br /&gt;
| participant_params&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
| Strong parameters: list of attributes allowed for participant creation or update&lt;br /&gt;
|-&lt;br /&gt;
| filter_participants_by_user&lt;br /&gt;
| Filters participants based on the provided user. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by user, if provided&lt;br /&gt;
|-&lt;br /&gt;
| filter_participants_by_assignment&lt;br /&gt;
| Filters participants based on the provided assignment. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by assignment, if provided&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| Validates that the authorization parameter is present and is one of the following valid authorizations: reader, reviewer, submitter, mentor&lt;br /&gt;
| Ensures authorization param is valid and returns it in lowercase; otherwise returns error response&lt;br /&gt;
|-&lt;br /&gt;
| find_user / find_assignment / find_participant&lt;br /&gt;
| Finds a user/assignment/participant by ID and returns it&lt;br /&gt;
| Fetches the corresponding record by ID; renders a not-found error if record does not exist&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Proposed Testing Changes==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add more descriptive comments for tests&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that authorizations are updated correctly&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that inputted path parameters are not missing and valid inputs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Tests at Line 222 and Line 231 are redundant, as the only difference in the test is the authorization, which would not affect what happens if a participant is not found&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
As this is a refactoring project, most of our work on the codebase involved cleaning up the current codebase to better align with foundational code style principles rather than introducing any of kind of new functionality. Our primary focus is to make the code more readable and easier to work with than before. We also took the liberty of fixing some minor errors that we found along the way.&lt;br /&gt;
&lt;br /&gt;
==Changelog==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Naming changes to multiple functions for better clarity and consistency&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Changed HTML status message for &amp;lt;code&amp;gt;show()&amp;lt;/code&amp;gt; from 201 (Created) to 200 (OK) as it is a better fit&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Created the &amp;lt;code&amp;gt;assign_participant_permissions()&amp;lt;/code&amp;gt; method&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Introduced two additional tests and removed a redundant one (see Testing Plan for more details)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Removed redundant queries to &amp;lt;code&amp;gt;Participant.all()&amp;lt;/code&amp;gt; in both filtering methods&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Updated method comments to be more descriptive (see comments table in Design)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Function Name Changes==&lt;br /&gt;
&lt;br /&gt;
The previous implementation had several functions that were strangely named or had names that could be easily misconstrued. The name changes remain the same from the proposal and design section, but for the purpose of clarity, the rationale for each of the functions will be provided below.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
These two functions are meant to render a list of participants given a &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt; respectively. Based on the name alone, it is difficult to tell that the function would render a User/Assignment or Participants. In order to remedy this, we chose the names &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;. The word &amp;quot;list&amp;quot; was replaced by &amp;quot;render&amp;quot; in order to better denote that it is rendering something (json in this case) and the &amp;quot;by&amp;quot; is added to emphasize that the User and Assignment are being used as parameters to search for the Participants. This provides a much clearer picture of what these functions should do compared to before.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; function's name was too vague to be particularly useful in identifying its purpose. To be more accurate, the function was meant to add the user to a given assignment, which would return a participant from the assignment's &amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; function. The new name of the function provides much more context to what it does (&amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_user_participants&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_assignment_participants&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Similar to the list methods that were previously mentioned, it is difficult to tell what exactly these two functions do. While it can be easily seen that it filters something, what is being filtered can be easily mistaken (e.g. does it filter users by participants or participants by users?). The new names, &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt; are much clearer in defining that the User and Assignment are being used as the filter parameters for the function.&lt;br /&gt;
&lt;br /&gt;
==HTML Status Code Change for &amp;lt;code&amp;gt;GET&amp;lt;/code&amp;gt; Call==&lt;br /&gt;
&lt;br /&gt;
The status code being used for this was previously 201, denoting &amp;quot;successful creation&amp;quot;. We have corrected this to a simple 200 code, which signifies an &amp;quot;ok&amp;quot; status message. This issue was actually identified by ChatGPT while we were dowsing for potential issues.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Test modified&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# Tests whether a participant returns properly if provided with a valid Participant ID&lt;br /&gt;
response '200', 'Returns a participant' do&lt;br /&gt;
  let(:id) { participant2.id }&lt;br /&gt;
&lt;br /&gt;
  run_test! do |response|&lt;br /&gt;
    data = JSON.parse(response.body)&lt;br /&gt;
    expect(data['user_id']).to eq(studenta.id)&lt;br /&gt;
    expect(data['assignment_id']).to eq(assignment2.id)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Redundant &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; Queries Removed==&lt;br /&gt;
&lt;br /&gt;
This issue was initially caught by the LLM, ChatGPT, that the team was using in order to find potential issues. We found that simply using &amp;lt;code&amp;gt;Participant.where()&amp;lt;/code&amp;gt; removed the need for the &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; query entirely while changing nothing else about the function, reducing the amount of queries necessary to call the filtering methods, &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# New function&lt;br /&gt;
def filter_participants_by_user(user)&lt;br /&gt;
  participants = Participant.where(user_id: user.id) if user # This would simply get the participants given the proper user ID&lt;br /&gt;
  participants.order(:id)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# Old function&lt;br /&gt;
def filter_participants_by_user(user)&lt;br /&gt;
  participants = Participant.all() # This would obtain the entire list of participants rather than just the necessary ones&lt;br /&gt;
  participants = participants.where(user_id: user.id) if user&lt;br /&gt;
  participants.order(:id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==New Private Method: &amp;lt;code&amp;gt;assign_participant_permissions()&amp;lt;/code&amp;gt;==&lt;br /&gt;
&lt;br /&gt;
The reasoning behind the addition of this method is because of a repeated piece of code that existed in the previous implementation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
participant.authorization = authorization&lt;br /&gt;
participant.can_submit = permissions[:can_submit]&lt;br /&gt;
participant.can_review = permissions[:can_review]&lt;br /&gt;
participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This was repeated in two different contexts: when the Participant was updated or created. This is a violation of the DRY principle, as the same code is repeated multiple times where it could have been reduced to make it more easily readable. In order to resolve this issue, we simply turned this code snippet into a private method that can be called within &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  # An authorization string containing the participant's role is taken and used to determine&lt;br /&gt;
  # what permissions will be allocated to the participant. Each of these permissions will&lt;br /&gt;
  # then be assigned to the Participant's database permission attributes.&lt;br /&gt;
  #&lt;br /&gt;
  # @param [String] authorization: An authorization string that represents the participant's role&lt;br /&gt;
  # @param [Participant] participant: The participant whose authorization permissions are being updated&lt;br /&gt;
  def assign_participant_permissions(authorization, participant)&lt;br /&gt;
    # Call helper method from participants_helper to retrieve a dictionary containing the&lt;br /&gt;
    # appropriate permission boolean values for the role specified by the authorization string&lt;br /&gt;
    permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
    # Assigns each of the boolean permission values to their respective database counterparts&lt;br /&gt;
    participant.authorization = authorization&lt;br /&gt;
    participant.can_submit = permissions[:can_submit]&lt;br /&gt;
    participant.can_review = permissions[:can_review]&lt;br /&gt;
    participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
    participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Description:===&lt;br /&gt;
&lt;br /&gt;
An authorization string containing the participant's role is taken and used to determine what permissions will be allocated to the participant. Each of these permissions will then be assigned to the Participant's database permission attributes.&lt;br /&gt;
&lt;br /&gt;
===Parameters:===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt;: An authorization string that represents the participant's role. This can be either reader, reviewer, submitter, or mentor.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant&amp;lt;/code&amp;gt;: The participant whose attributes are being updated. This is passed in to be modified by the function to be used to assign each of the participant's attribute values that are representative of its assigned role.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Behavior===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Use &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;participants_helper&amp;lt;/code&amp;gt; in order to get all necessary permission boolean values for a given participant role&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Assign each of the permission boolean values (&amp;lt;code&amp;gt;can_submit&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_review&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_take_quiz&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_mentor&amp;lt;/code&amp;gt;)&amp;lt;/li&amp;gt; from the helper method to their respective database attribute counterparts in Participant&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Post-Demo Changes==&lt;br /&gt;
&lt;br /&gt;
There were three notable topics that were brought up during the final demo presentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The renaming of &amp;lt;code&amp;gt;get_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;get_participants_by_assignment&amp;lt;/code&amp;gt; to something more suitable to its purpose in rendering the JSON of a list of participants&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Consider the application of &amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; within &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Update the wiki to provide descriptions for each of the methods included in &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt; (See Methods subsection in the Implementation section)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Renaming &amp;lt;code&amp;gt;get_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;get_participants_by_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
These two functions were renamed (once again) to something that better fit the functionality and purpose of the function. Since these functions are meant to render the lists of participants gotten from their respective parameters and use the ID values for each, both of the functions were renamed to &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt; respectively. The renaming of the filter methods was also brought up, but those functions actually do use the objects themselves as parameters, so have been left as is for the time being.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; within &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
We reconsidered the use of these methods within the controller since it was somewhat odd that it would have these methods. However, we concluded that, since the find methods are helper methods that are private and not open to be used by other parts of the code, to be fine to leave as is. This is mostly because they are simple helper methods that get the current user and assignment and return them, rendering an error if they do not exist.&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches all participants associated with the specified user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;user_id [Integer]&amp;lt;/code&amp;gt;: ID of the user&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; A JSON array of participant objects&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized for the action&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If the user does not exist&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If the query fails unexpectedly&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Renamed from &amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def render_participants_by_user_id&lt;br /&gt;
    user = find_user if params[:user_id].present?&lt;br /&gt;
    return if params[:user_id].present? &amp;amp;&amp;amp; user.nil?&lt;br /&gt;
&lt;br /&gt;
    participants = filter_participants_by_user(user)&lt;br /&gt;
&lt;br /&gt;
    if participants.nil?&lt;br /&gt;
      render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participants, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Fetches all participants associated with a specific assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment_id [Integer]&amp;lt;/code&amp;gt;: ID of the assignment&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; A JSON array of participant objects&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized for the action&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If the assignment does not exist&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If the query fails unexpectedly&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Renamed from &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def render_participants_by_assignment_id&lt;br /&gt;
    assignment = find_assignment if params[:assignment_id].present?&lt;br /&gt;
    return if params[:assignment_id].present? &amp;amp;&amp;amp; assignment.nil?&lt;br /&gt;
&lt;br /&gt;
    participants = filter_participants_by_assignment(assignment)&lt;br /&gt;
&lt;br /&gt;
    if participants.nil?&lt;br /&gt;
      render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participants, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;show&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches the details of a specific participant by their ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; JSON representation of the participant&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If the participant does not exist&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If the lookup fails&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Standardized participant lookup to return proper HTTP codes&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def show&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if participant.nil?&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adds a user as a participant to an assignment with the specified authorization (role and permissions).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant[user_id] [Integer]&amp;lt;/code&amp;gt;: ID of the user&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant[assignment_id] [Integer]&amp;lt;/code&amp;gt;: ID of the assignment&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: Role assigned to the participant (reader, reviewer, submitter, mentor)&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;201 Created:&amp;lt;/b&amp;gt; Participant successfully added&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If user or assignment is not found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If authorization is invalid or save fails&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;The naming convention was made similar to other methods&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def add_participant_to_assignment&lt;br /&gt;
    user = find_user&lt;br /&gt;
    return unless user&lt;br /&gt;
&lt;br /&gt;
    assignment = find_assignment&lt;br /&gt;
    return unless assignment&lt;br /&gt;
&lt;br /&gt;
    authorization = validate_authorization&lt;br /&gt;
    return unless authorization&lt;br /&gt;
&lt;br /&gt;
    participant = assignment.add_participant(user)&lt;br /&gt;
    assign_participant_permissions(authorization, participant)&lt;br /&gt;
&lt;br /&gt;
    if participant.save&lt;br /&gt;
      render json: participant, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;update_authorization&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Updates the authorization (role) of an existing participant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: New role to assign (reader, reviewer, submitter, mentor)&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;201 Created:&amp;lt;/b&amp;gt; Authorization updated successfully&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If participant is not found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If authorization is invalid&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Added validation for authorization role values&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = find_participant&lt;br /&gt;
    return unless participant&lt;br /&gt;
&lt;br /&gt;
    authorization = validate_authorization&lt;br /&gt;
    return unless authorization&lt;br /&gt;
&lt;br /&gt;
    assign_participant_permissions(authorization, participant)&lt;br /&gt;
&lt;br /&gt;
    if participant.save&lt;br /&gt;
      render json: participant, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;destroy&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deletes a participant from the system. Optionally includes assignment and team context in the success message.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment_id [Integer] (optional)&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;team_id [Integer] (optional)&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; Success message indicating deletion&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If participant is not found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If deletion fails&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Enhanced success message based on team/assignment presence&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def destroy&lt;br /&gt;
    participant = Participant.find_by(id: params[:id])&lt;br /&gt;
  &lt;br /&gt;
    if participant.nil?&lt;br /&gt;
      render json: { error: 'Not Found' }, status: :not_found&lt;br /&gt;
    elsif participant.destroy&lt;br /&gt;
      successful_deletion_message = if params[:team_id].nil?&lt;br /&gt;
                                      &amp;quot;Participant #{params[:id]} in Assignment #{params[:assignment_id]} has been deleted successfully!&amp;quot;&lt;br /&gt;
                                    else&lt;br /&gt;
                                      &amp;quot;Participant #{params[:id]} in Team #{params[:team_id]} of Assignment #{params[:assignment_id]} has been deleted successfully!&amp;quot;&lt;br /&gt;
                                    end&lt;br /&gt;
      render json: { message: successful_deletion_message }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;participants_params&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Defines the strong parameters allowed when creating or updating a participant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant&amp;lt;/code&amp;gt;: Hash containing fields like user_id, assignment_id, authorization, etc.&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Permitted parameter hash for participant creation/update&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Updated to include all permission and assignment-related fields&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def participant_params&lt;br /&gt;
    params.require(:participant).permit(:user_id, :assignment_id, :authorization, :can_submit,&lt;br /&gt;
                                        :can_review, :can_take_quiz, :can_mentor, :handle,&lt;br /&gt;
                                        :team_id, :join_team_request_id, :permission_granted,&lt;br /&gt;
                                        :topic, :current_stage, :stage_deadline)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches participants associated with a given user, ordered by ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;user [User]&amp;lt;/code&amp;gt;: User object&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Ordered list of participants for the user&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def filter_participants_by_user(user)&lt;br /&gt;
    participants = Participant.where(user_id: user.id) if user&lt;br /&gt;
    participants.order(:id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches participants associated with a given assignment, ordered by ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment [Assignment]&amp;lt;/code&amp;gt;: Assignment object&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Ordered list of participants for the assignment&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def filter_participants_by_assignment(assignment)&lt;br /&gt;
    participants = Participant.where(assignment_id: assignment.id) if assignment&lt;br /&gt;
    participants.order(:id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finds a user based on the provided user_id.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;user_id [Integer]&amp;lt;/code&amp;gt;: ID of the user&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;User object if found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;404 error if not found&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Centralized user lookup and error handling&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_user&lt;br /&gt;
    user_id = params[:user_id]&lt;br /&gt;
    user = User.find_by(id: user_id)&lt;br /&gt;
    render json: { error: 'User not found' }, status: :not_found unless user&lt;br /&gt;
    user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finds an assignment based on the provided assignment_id.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment_id [Integer]&amp;lt;/code&amp;gt;: ID of the assignment&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Assignment object if found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;404 error if not found&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Centralized assignment lookup and error handling&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_assignment&lt;br /&gt;
    assignment_id = params[:assignment_id]&lt;br /&gt;
    assignment = Assignment.find_by(id: assignment_id)&lt;br /&gt;
    render json: { error: 'Assignment not found' }, status: :not_found unless assignment&lt;br /&gt;
    assignment&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&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;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finds a participant based on the provided ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Participant object if found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;404 error if not found&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Centralized participant lookup and error handling&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_participant&lt;br /&gt;
    participant_id = params[:id]&lt;br /&gt;
    participant = Participant.find_by(id: participant_id)&lt;br /&gt;
    render json: { error: 'Participant not found' }, status: :not_found unless participant&lt;br /&gt;
    participant&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;assign_participant_permissions&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Assigns permission flags to a participant based on the authorization role provided.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: Role to assign&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant [Participant]&amp;lt;/code&amp;gt;: Participant object&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Participant object with updated permissions&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Added dynamic permission setting based on role&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def assign_participant_permissions(authorization, participant)&lt;br /&gt;
    # Call helper method from participants_helper to retrieve a dictionary containing the&lt;br /&gt;
    # appropriate permission boolean values for the role specified by the authorization string&lt;br /&gt;
    permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
    # Assigns each of the boolean permission values to their respective database counterparts&lt;br /&gt;
    participant.authorization = authorization&lt;br /&gt;
    participant.can_submit = permissions[:can_submit]&lt;br /&gt;
    participant.can_review = permissions[:can_review]&lt;br /&gt;
    participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
    participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;validate_authorization&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Validates that the authorization string is present and one of the accepted roles.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: Authorization role&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Validated authorization string&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;422 error if invalid&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Standardized authorization validation across endpoints&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def validate_authorization&lt;br /&gt;
    valid_authorizations = %w[reader reviewer submitter mentor]&lt;br /&gt;
    authorization = params[:authorization]&lt;br /&gt;
    authorization = authorization.downcase if authorization.present?&lt;br /&gt;
&lt;br /&gt;
    unless authorization&lt;br /&gt;
      render json: { error: 'authorization is required' }, status: :unprocessable_entity&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    unless valid_authorizations.include?(authorization)&lt;br /&gt;
      render json: { error: 'authorization not valid. Valid authorizations are: Reader, Reviewer, Submitter, Mentor' },&lt;br /&gt;
             status: :unprocessable_entity&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    authorization&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Testing Plan=&lt;br /&gt;
&lt;br /&gt;
Of this implementation, also existing 25 tests are passing. We have also given each test their respective IDs within &amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt; as well so that they may be more easily identifiable. For more information about the previous testing plan, please refer to the previous implementation's page here: [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2484._Reimplement_participants_controller.rb]&lt;br /&gt;
&lt;br /&gt;
Below are any modifications to the existing test file (&amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt;) that we have made during the course of this project, alongside the descriptions and rationales behind them:&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
Below are the tests that are included in this implementation. We have updated the test descriptions to include more accurate and detailed information about each of the tests as well. Any tests that have been modified or new will be specified as such:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Retrieve participants by valid user ID (should return participant data)&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Retrieve participants by user ID with no participants (should return empty array)&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Retrieve participants with non-existent user ID (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Retrieve participants by user ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Retrieve participants by valid assignment ID (should return participant data)&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Retrieve participants by non-existent assignment ID (should return 'Assignment not found')&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Retrieve participants by assignment ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Retrieve a participant by valid ID (should return participant details)&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Retrieve a participant by non-existent ID (should return 'Not Found')&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Retrieve a participant by ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Delete a participant by valid ID (should return deletion success message)&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Delete a participant by non-existent ID (should return 'Not Found')&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Delete a participant by ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Update participant authorization with valid data (should return updated authorization)&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Update participant authorization with non-existent participant ID (should return 'Participant not found')&lt;br /&gt;
|-&lt;br /&gt;
| 16 || Update participant authorization with invalid role (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 17 || Update participant authorization with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 18 || Add a participant successfully (should return participant data with authorization)&lt;br /&gt;
|-&lt;br /&gt;
| 19 || Add a participant that already exists (should return duplicate participant error)&lt;br /&gt;
|-&lt;br /&gt;
| 20 || Add a participant with non-existent user ID (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 21 || Add a participant with non-existent assignment ID (should return 'Assignment not found')&lt;br /&gt;
|-&lt;br /&gt;
| 22 || Add a participant with invalid authorization (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 23 || Add a participant with unsupported authorization format (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 24 (NEW) || Add a participant missing user_id in request body (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 25 (NEW) || Add a participant missing assignment_id in request body (should return 'Assignment not found')&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Removed Tests==&lt;br /&gt;
&lt;br /&gt;
These are any tests that we have modified or removed from the previous testing plan. If the test ID is denoted by (Previously), that means that the ID shown was part of the previous implementation's testing plan.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Modification Description &lt;br /&gt;
|-&lt;br /&gt;
| (Previously) 22 || This test was removed as it was redundant. While it is important to check the authorization of the participant that would be invalid, the invalid ID used for this test is a duplicate of the previous test, meaning the result is guaranteed to match that of the previous test regardless of what is meant to be tested.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Next Steps=&lt;br /&gt;
&lt;br /&gt;
Being able to implement this could potentially simplify rendering to the view somewhat in that it could handle simple HTML status code handling. Below are some examples of implementations to serve as a point of reference:&lt;br /&gt;
&lt;br /&gt;
===Example 1===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# Checks if a target object (participant or participants) is not nil and then renders the object.&lt;br /&gt;
# If the object is nil, renders the object errors and sends a not_found_status and if the object&lt;br /&gt;
# exists, renders the object and sends a success status&lt;br /&gt;
# not_found_status default: :unprocessable_entity (422)&lt;br /&gt;
# success_status default: :ok (200)&lt;br /&gt;
def render_object_or_error(object, not_found_status: :unprocessable_entity, success_status: :ok)&lt;br /&gt;
  if object.nil?&lt;br /&gt;
    render json: { error: 'Resource not found' }, status: not_found_status&lt;br /&gt;
  elsif object.respond_to?(:errors) &amp;amp;&amp;amp; object.errors.any?&lt;br /&gt;
    render json: object.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: object, status: success_status&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example is modeled to be specific to the most common use case for this function in the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; by returning the default 422 and 200 error and success codes that are used by three instances of JSON rendering where it checks for whether a list of participants or a single participant is nil. These default values for the status codes are mainly to cover those instances, but could be changed to something else if necessary. The &amp;lt;code&amp;gt;object&amp;lt;/code&amp;gt; parameter is representative of the object that was meant to be rendered given the success or failure of the operation.&lt;br /&gt;
&lt;br /&gt;
===Example 2===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
def render_object_if(conditional, object, error_status, success_status)&lt;br /&gt;
  if conditional&lt;br /&gt;
    render json: { error: 'Resource not found' }, status: error_status&lt;br /&gt;
  else&lt;br /&gt;
    render json: object, status: success_status&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example is a more generic implementation of the function, mandating the error and success status codes rather than providing default values. The point of this was to emphasize readability when glancing over the use of this function. For example, being able to tell that seeing the function being used would immediately tell the reader what the success and failure states were immediately without having to find and inspect the function itself. The &amp;lt;code&amp;gt;conditional&amp;lt;/code&amp;gt; parameter would also allow the function to act similarly to a more readable ternary statement made for rendering.&lt;br /&gt;
&lt;br /&gt;
Implementing this successfully would reduce the amount of repetitive code being used within the controller, as the if-else view rendering is very common in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. We were unable to implement it within our given timeframe, so we opted to divert our focus on other, important tasks that we needed to do.&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Relevant Links =&lt;br /&gt;
&lt;br /&gt;
Pull Request [https://github.com/expertiza/reimplementation-back-end/pull/192] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=165285</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=165285"/>
		<updated>2025-04-27T19:41:56Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* filter_participants_by_user */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
==Video Overview==&lt;br /&gt;
&lt;br /&gt;
https://youtu.be/4kfz0hrmSg4&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; In the video it shows the test file at the end, but does not mention a last-minute change that numbers all of the tests to make it much easier to keep track of each of the tests and which ones are passing.&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Use of Large Language Models (LLMs)=&lt;br /&gt;
&lt;br /&gt;
For this project, we are using ChatGPT as an LLM helper in determining what issues there are within the code. The use of LLMs in this project will likely be limited to probing for potential issues that exist within the system.&lt;br /&gt;
&lt;br /&gt;
Below we have organized the following prompts and a summary of the output in a table:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 25%&amp;quot; | Prompts !! LLM Output Summary&lt;br /&gt;
|-&lt;br /&gt;
| [Code from &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;]&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt; Are there any ways where we can refactor the code to improve readability, DRYness, and clarity of error handling?&lt;br /&gt;
|| It recognized some of the issues we, as a team, had already identified and suggested fixes that were similar to what we outlined: &amp;lt;b&amp;gt;Redundant JSON Rendering Code&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_Redundant_JSON_Rendering_Code] and &amp;lt;b&amp;gt;Simplifying the Assignment of Participant Fields&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_the_Assignment_of_Participant_Fields]. Additionally, it suggested minor changes that we could implement, such as using &amp;lt;code&amp;gt;Participant.where(...)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; to filter out the code more efficiently instead of getting all database instances every time, as well as the use of strong parameters in &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update_authorization()&amp;lt;/code&amp;gt; to avoid having to implement custom parsing techniques. It also recommends renaming the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; function to something more specific in relation to its purpose (adding a &amp;lt;code&amp;gt;Participant&amp;lt;/code&amp;gt; to an &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Potential Redundant Tests in &amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|| The tests on line 222 and 231 are redundant as only the authorization differs. (Note: This should be investigated to see whether or not this is necessary)&lt;br /&gt;
|-&lt;br /&gt;
| Checking for issues with the current testing files&lt;br /&gt;
|| The &amp;quot;Get Participant by ID call&amp;quot; test was returning a 201 status code instead of the more suitable 200 code&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed information on what prompts we used and the output we got, please visit the page here: [https://docs.google.com/document/d/105_U_Coky-edx7n-tFhD2B5RqmVXxEsKPW_qUaf7bQU/edit?usp=sharing].&lt;br /&gt;
&lt;br /&gt;
=Requirements=&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Some API functions are not returning the correct HTML status messages (e.g. test on line 136 returns 201 instead of 200)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Documentation and comments can be somewhat vague&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;In-line comments should be more descriptive, explaining what the code does in more details&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Tests are not described via comments, but in name alone; some more descriptive comments that explain the tests in more detail would be ideal&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Design / Proposed Solution=&lt;br /&gt;
&lt;br /&gt;
Based on the previous implementation's controller diagram, we have created a new version that contains our proposed changes and modifications to &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[File:Participants_controller_refactor_v1.2.png]]&lt;br /&gt;
&lt;br /&gt;
==Simplifying Redundant JSON Rendering Code==&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Simplifying the Assignment of Participant Fields==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update()&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Provide More Clarity in Function Names==&lt;br /&gt;
&lt;br /&gt;
There are some functions that are somewhat unclear/vague in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. For example, the &amp;lt;code&amp;gt;list_user_participants()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== - Suggested Method Name Improvements ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Old Method Name&lt;br /&gt;
! New Method Name&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Clearer and more descriptive&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Clearer and more descriptive and is consistent with the other get method&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;&lt;br /&gt;
| Describes both creation and authorization setup of participant to assignment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_user_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt;&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_assignment_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Improve Documentation and Comments==&lt;br /&gt;
&lt;br /&gt;
Some of the documentation and in-line comments can be somewhat vague. This can lead to misconceptions about how some functions work or how some of the code can function. Below are potential improvements we plan to make for function descriptions, though these may change with the final implementation.&lt;br /&gt;
&lt;br /&gt;
=== Improved Method Comments ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Original Comment&lt;br /&gt;
! Refactored Comment&lt;br /&gt;
|-&lt;br /&gt;
| render_participants_by_user_id&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
| Retrieves all participants associated with the specified user ID&lt;br /&gt;
|-&lt;br /&gt;
| render_participants_by_assignment_id&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
| Retrieves all participants linked to the specified assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
| Fetch and return the participant with the given ID&lt;br /&gt;
|-&lt;br /&gt;
| add_participant_to_assignment&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
| Creates a new participant for a given assignment and assigns appropriate authorization and permissions&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
| Updates the participant’s authorization role and related permissions&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
| Deletes the participant identified by the given ID and returns a confirmation message&lt;br /&gt;
|-&lt;br /&gt;
| participant_params&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
| Strong parameters: list of attributes allowed for participant creation or update&lt;br /&gt;
|-&lt;br /&gt;
| filter_participants_by_user&lt;br /&gt;
| Filters participants based on the provided user. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by user, if provided&lt;br /&gt;
|-&lt;br /&gt;
| filter_participants_by_assignment&lt;br /&gt;
| Filters participants based on the provided assignment. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by assignment, if provided&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| Validates that the authorization parameter is present and is one of the following valid authorizations: reader, reviewer, submitter, mentor&lt;br /&gt;
| Ensures authorization param is valid and returns it in lowercase; otherwise returns error response&lt;br /&gt;
|-&lt;br /&gt;
| find_user / find_assignment / find_participant&lt;br /&gt;
| Finds a user/assignment/participant by ID and returns it&lt;br /&gt;
| Fetches the corresponding record by ID; renders a not-found error if record does not exist&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Proposed Testing Changes==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add more descriptive comments for tests&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that authorizations are updated correctly&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that inputted path parameters are not missing and valid inputs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Tests at Line 222 and Line 231 are redundant, as the only difference in the test is the authorization, which would not affect what happens if a participant is not found&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
As this is a refactoring project, most of our work on the codebase involved cleaning up the current codebase to better align with foundational code style principles rather than introducing any of kind of new functionality. Our primary focus is to make the code more readable and easier to work with than before. We also took the liberty of fixing some minor errors that we found along the way.&lt;br /&gt;
&lt;br /&gt;
==Changelog==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Naming changes to multiple functions for better clarity and consistency&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Changed HTML status message for &amp;lt;code&amp;gt;show()&amp;lt;/code&amp;gt; from 201 (Created) to 200 (OK) as it is a better fit&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Created the &amp;lt;code&amp;gt;assign_participant_permissions()&amp;lt;/code&amp;gt; method&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Introduced two additional tests and removed a redundant one (see Testing Plan for more details)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Removed redundant queries to &amp;lt;code&amp;gt;Participant.all()&amp;lt;/code&amp;gt; in both filtering methods&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Updated method comments to be more descriptive (see comments table in Design)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Function Name Changes==&lt;br /&gt;
&lt;br /&gt;
The previous implementation had several functions that were strangely named or had names that could be easily misconstrued. The name changes remain the same from the proposal and design section, but for the purpose of clarity, the rationale for each of the functions will be provided below.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
These two functions are meant to render a list of participants given a &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt; respectively. Based on the name alone, it is difficult to tell that the function would render a User/Assignment or Participants. In order to remedy this, we chose the names &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;. The word &amp;quot;list&amp;quot; was replaced by &amp;quot;render&amp;quot; in order to better denote that it is rendering something (json in this case) and the &amp;quot;by&amp;quot; is added to emphasize that the User and Assignment are being used as parameters to search for the Participants. This provides a much clearer picture of what these functions should do compared to before.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; function's name was too vague to be particularly useful in identifying its purpose. To be more accurate, the function was meant to add the user to a given assignment, which would return a participant from the assignment's &amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; function. The new name of the function provides much more context to what it does (&amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_user_participants&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_assignment_participants&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Similar to the list methods that were previously mentioned, it is difficult to tell what exactly these two functions do. While it can be easily seen that it filters something, what is being filtered can be easily mistaken (e.g. does it filter users by participants or participants by users?). The new names, &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt; are much clearer in defining that the User and Assignment are being used as the filter parameters for the function.&lt;br /&gt;
&lt;br /&gt;
==HTML Status Code Change for &amp;lt;code&amp;gt;GET&amp;lt;/code&amp;gt; Call==&lt;br /&gt;
&lt;br /&gt;
The status code being used for this was previously 201, denoting &amp;quot;successful creation&amp;quot;. We have corrected this to a simple 200 code, which signifies an &amp;quot;ok&amp;quot; status message. This issue was actually identified by ChatGPT while we were dowsing for potential issues.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Test modified&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# Tests whether a participant returns properly if provided with a valid Participant ID&lt;br /&gt;
response '200', 'Returns a participant' do&lt;br /&gt;
  let(:id) { participant2.id }&lt;br /&gt;
&lt;br /&gt;
  run_test! do |response|&lt;br /&gt;
    data = JSON.parse(response.body)&lt;br /&gt;
    expect(data['user_id']).to eq(studenta.id)&lt;br /&gt;
    expect(data['assignment_id']).to eq(assignment2.id)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Redundant &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; Queries Removed==&lt;br /&gt;
&lt;br /&gt;
This issue was initially caught by the LLM, ChatGPT, that the team was using in order to find potential issues. We found that simply using &amp;lt;code&amp;gt;Participant.where()&amp;lt;/code&amp;gt; removed the need for the &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; query entirely while changing nothing else about the function, reducing the amount of queries necessary to call the filtering methods, &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# New function&lt;br /&gt;
def filter_participants_by_user(user)&lt;br /&gt;
  participants = Participant.where(user_id: user.id) if user # This would simply get the participants given the proper user ID&lt;br /&gt;
  participants.order(:id)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# Old function&lt;br /&gt;
def filter_participants_by_user(user)&lt;br /&gt;
  participants = Participant.all() # This would obtain the entire list of participants rather than just the necessary ones&lt;br /&gt;
  participants = participants.where(user_id: user.id) if user&lt;br /&gt;
  participants.order(:id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==New Private Method: &amp;lt;code&amp;gt;assign_participant_permissions()&amp;lt;/code&amp;gt;==&lt;br /&gt;
&lt;br /&gt;
The reasoning behind the addition of this method is because of a repeated piece of code that existed in the previous implementation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
participant.authorization = authorization&lt;br /&gt;
participant.can_submit = permissions[:can_submit]&lt;br /&gt;
participant.can_review = permissions[:can_review]&lt;br /&gt;
participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This was repeated in two different contexts: when the Participant was updated or created. This is a violation of the DRY principle, as the same code is repeated multiple times where it could have been reduced to make it more easily readable. In order to resolve this issue, we simply turned this code snippet into a private method that can be called within &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  # An authorization string containing the participant's role is taken and used to determine&lt;br /&gt;
  # what permissions will be allocated to the participant. Each of these permissions will&lt;br /&gt;
  # then be assigned to the Participant's database permission attributes.&lt;br /&gt;
  #&lt;br /&gt;
  # @param [String] authorization: An authorization string that represents the participant's role&lt;br /&gt;
  # @param [Participant] participant: The participant whose authorization permissions are being updated&lt;br /&gt;
  def assign_participant_permissions(authorization, participant)&lt;br /&gt;
    # Call helper method from participants_helper to retrieve a dictionary containing the&lt;br /&gt;
    # appropriate permission boolean values for the role specified by the authorization string&lt;br /&gt;
    permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
    # Assigns each of the boolean permission values to their respective database counterparts&lt;br /&gt;
    participant.authorization = authorization&lt;br /&gt;
    participant.can_submit = permissions[:can_submit]&lt;br /&gt;
    participant.can_review = permissions[:can_review]&lt;br /&gt;
    participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
    participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Description:===&lt;br /&gt;
&lt;br /&gt;
An authorization string containing the participant's role is taken and used to determine what permissions will be allocated to the participant. Each of these permissions will then be assigned to the Participant's database permission attributes.&lt;br /&gt;
&lt;br /&gt;
===Parameters:===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt;: An authorization string that represents the participant's role. This can be either reader, reviewer, submitter, or mentor.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant&amp;lt;/code&amp;gt;: The participant whose attributes are being updated. This is passed in to be modified by the function to be used to assign each of the participant's attribute values that are representative of its assigned role.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Behavior===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Use &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;participants_helper&amp;lt;/code&amp;gt; in order to get all necessary permission boolean values for a given participant role&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Assign each of the permission boolean values (&amp;lt;code&amp;gt;can_submit&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_review&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_take_quiz&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_mentor&amp;lt;/code&amp;gt;)&amp;lt;/li&amp;gt; from the helper method to their respective database attribute counterparts in Participant&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Post-Demo Changes==&lt;br /&gt;
&lt;br /&gt;
There were three notable topics that were brought up during the final demo presentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The renaming of &amp;lt;code&amp;gt;get_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;get_participants_by_assignment&amp;lt;/code&amp;gt; to something more suitable to its purpose in rendering the JSON of a list of participants&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Consider the application of &amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; within &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Update the wiki to provide descriptions for each of the methods included in &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt; (See Methods subsection in the Implementation section)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Renaming &amp;lt;code&amp;gt;get_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;get_participants_by_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
These two functions were renamed (once again) to something that better fit the functionality and purpose of the function. Since these functions are meant to render the lists of participants gotten from their respective parameters and use the ID values for each, both of the functions were renamed to &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt; respectively. The renaming of the filter methods was also brought up, but those functions actually do use the objects themselves as parameters, so have been left as is for the time being.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; within &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
We reconsidered the use of these methods within the controller since it was somewhat odd that it would have these methods. However, we concluded that, since the find methods are helper methods that are private and not open to be used by other parts of the code, to be fine to leave as is. This is mostly because they are simple helper methods that get the current user and assignment and return them, rendering an error if they do not exist.&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches all participants associated with the specified user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;user_id [Integer]&amp;lt;/code&amp;gt;: ID of the user&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; A JSON array of participant objects&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized for the action&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If the user does not exist&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If the query fails unexpectedly&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Renamed from &amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def render_participants_by_user_id&lt;br /&gt;
    user = find_user if params[:user_id].present?&lt;br /&gt;
    return if params[:user_id].present? &amp;amp;&amp;amp; user.nil?&lt;br /&gt;
&lt;br /&gt;
    participants = filter_participants_by_user(user)&lt;br /&gt;
&lt;br /&gt;
    if participants.nil?&lt;br /&gt;
      render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participants, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Fetches all participants associated with a specific assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment_id [Integer]&amp;lt;/code&amp;gt;: ID of the assignment&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; A JSON array of participant objects&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized for the action&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If the assignment does not exist&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If the query fails unexpectedly&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Renamed from &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def render_participants_by_assignment_id&lt;br /&gt;
    assignment = find_assignment if params[:assignment_id].present?&lt;br /&gt;
    return if params[:assignment_id].present? &amp;amp;&amp;amp; assignment.nil?&lt;br /&gt;
&lt;br /&gt;
    participants = filter_participants_by_assignment(assignment)&lt;br /&gt;
&lt;br /&gt;
    if participants.nil?&lt;br /&gt;
      render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participants, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;show&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches the details of a specific participant by their ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; JSON representation of the participant&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If the participant does not exist&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If the lookup fails&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Standardized participant lookup to return proper HTTP codes&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def show&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if participant.nil?&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adds a user as a participant to an assignment with the specified authorization (role and permissions).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant[user_id] [Integer]&amp;lt;/code&amp;gt;: ID of the user&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant[assignment_id] [Integer]&amp;lt;/code&amp;gt;: ID of the assignment&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: Role assigned to the participant (reader, reviewer, submitter, mentor)&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;201 Created:&amp;lt;/b&amp;gt; Participant successfully added&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If user or assignment is not found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If authorization is invalid or save fails&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Introduced role-based permission assignment during participant creation&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def add_participant_to_assignment&lt;br /&gt;
    user = find_user&lt;br /&gt;
    return unless user&lt;br /&gt;
&lt;br /&gt;
    assignment = find_assignment&lt;br /&gt;
    return unless assignment&lt;br /&gt;
&lt;br /&gt;
    authorization = validate_authorization&lt;br /&gt;
    return unless authorization&lt;br /&gt;
&lt;br /&gt;
    participant = assignment.add_participant(user)&lt;br /&gt;
    assign_participant_permissions(authorization, participant)&lt;br /&gt;
&lt;br /&gt;
    if participant.save&lt;br /&gt;
      render json: participant, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;update_authorization&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Updates the authorization (role) of an existing participant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: New role to assign (reader, reviewer, submitter, mentor)&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;201 Created:&amp;lt;/b&amp;gt; Authorization updated successfully&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If participant is not found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If authorization is invalid&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Added validation for authorization role values&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = find_participant&lt;br /&gt;
    return unless participant&lt;br /&gt;
&lt;br /&gt;
    authorization = validate_authorization&lt;br /&gt;
    return unless authorization&lt;br /&gt;
&lt;br /&gt;
    assign_participant_permissions(authorization, participant)&lt;br /&gt;
&lt;br /&gt;
    if participant.save&lt;br /&gt;
      render json: participant, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;destroy&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deletes a participant from the system. Optionally includes assignment and team context in the success message.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment_id [Integer] (optional)&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;team_id [Integer] (optional)&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; Success message indicating deletion&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If participant is not found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If deletion fails&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Enhanced success message based on team/assignment presence&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def destroy&lt;br /&gt;
    participant = Participant.find_by(id: params[:id])&lt;br /&gt;
  &lt;br /&gt;
    if participant.nil?&lt;br /&gt;
      render json: { error: 'Not Found' }, status: :not_found&lt;br /&gt;
    elsif participant.destroy&lt;br /&gt;
      successful_deletion_message = if params[:team_id].nil?&lt;br /&gt;
                                      &amp;quot;Participant #{params[:id]} in Assignment #{params[:assignment_id]} has been deleted successfully!&amp;quot;&lt;br /&gt;
                                    else&lt;br /&gt;
                                      &amp;quot;Participant #{params[:id]} in Team #{params[:team_id]} of Assignment #{params[:assignment_id]} has been deleted successfully!&amp;quot;&lt;br /&gt;
                                    end&lt;br /&gt;
      render json: { message: successful_deletion_message }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;participants_params&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Defines the strong parameters allowed when creating or updating a participant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant&amp;lt;/code&amp;gt;: Hash containing fields like user_id, assignment_id, authorization, etc.&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Permitted parameter hash for participant creation/update&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Updated to include all permission and assignment-related fields&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def participant_params&lt;br /&gt;
    params.require(:participant).permit(:user_id, :assignment_id, :authorization, :can_submit,&lt;br /&gt;
                                        :can_review, :can_take_quiz, :can_mentor, :handle,&lt;br /&gt;
                                        :team_id, :join_team_request_id, :permission_granted,&lt;br /&gt;
                                        :topic, :current_stage, :stage_deadline)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches participants associated with a given user, ordered by ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;user [User]&amp;lt;/code&amp;gt;: User object&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Ordered list of participants for the user&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def filter_participants_by_user(user)&lt;br /&gt;
    participants = Participant.where(user_id: user.id) if user&lt;br /&gt;
    participants.order(:id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches participants associated with a given assignment, ordered by ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment [Assignment]&amp;lt;/code&amp;gt;: Assignment object&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Ordered list of participants for the assignment&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def filter_participants_by_assignment(assignment)&lt;br /&gt;
    participants = Participant.where(assignment_id: assignment.id) if assignment&lt;br /&gt;
    participants.order(:id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finds a user based on the provided user_id.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;user_id [Integer]&amp;lt;/code&amp;gt;: ID of the user&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;User object if found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;404 error if not found&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Centralized user lookup and error handling&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_user&lt;br /&gt;
    user_id = params[:user_id]&lt;br /&gt;
    user = User.find_by(id: user_id)&lt;br /&gt;
    render json: { error: 'User not found' }, status: :not_found unless user&lt;br /&gt;
    user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finds an assignment based on the provided assignment_id.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment_id [Integer]&amp;lt;/code&amp;gt;: ID of the assignment&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Assignment object if found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;404 error if not found&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Centralized assignment lookup and error handling&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_assignment&lt;br /&gt;
    assignment_id = params[:assignment_id]&lt;br /&gt;
    assignment = Assignment.find_by(id: assignment_id)&lt;br /&gt;
    render json: { error: 'Assignment not found' }, status: :not_found unless assignment&lt;br /&gt;
    assignment&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&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;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finds a participant based on the provided ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Participant object if found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;404 error if not found&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Centralized participant lookup and error handling&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_participant&lt;br /&gt;
    participant_id = params[:id]&lt;br /&gt;
    participant = Participant.find_by(id: participant_id)&lt;br /&gt;
    render json: { error: 'Participant not found' }, status: :not_found unless participant&lt;br /&gt;
    participant&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;assign_participant_permissions&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Assigns permission flags to a participant based on the authorization role provided.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: Role to assign&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant [Participant]&amp;lt;/code&amp;gt;: Participant object&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Participant object with updated permissions&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Added dynamic permission setting based on role&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def assign_participant_permissions(authorization, participant)&lt;br /&gt;
    # Call helper method from participants_helper to retrieve a dictionary containing the&lt;br /&gt;
    # appropriate permission boolean values for the role specified by the authorization string&lt;br /&gt;
    permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
    # Assigns each of the boolean permission values to their respective database counterparts&lt;br /&gt;
    participant.authorization = authorization&lt;br /&gt;
    participant.can_submit = permissions[:can_submit]&lt;br /&gt;
    participant.can_review = permissions[:can_review]&lt;br /&gt;
    participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
    participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;validate_authorization&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Validates that the authorization string is present and one of the accepted roles.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: Authorization role&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Validated authorization string&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;422 error if invalid&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Standardized authorization validation across endpoints&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def validate_authorization&lt;br /&gt;
    valid_authorizations = %w[reader reviewer submitter mentor]&lt;br /&gt;
    authorization = params[:authorization]&lt;br /&gt;
    authorization = authorization.downcase if authorization.present?&lt;br /&gt;
&lt;br /&gt;
    unless authorization&lt;br /&gt;
      render json: { error: 'authorization is required' }, status: :unprocessable_entity&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    unless valid_authorizations.include?(authorization)&lt;br /&gt;
      render json: { error: 'authorization not valid. Valid authorizations are: Reader, Reviewer, Submitter, Mentor' },&lt;br /&gt;
             status: :unprocessable_entity&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    authorization&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Testing Plan=&lt;br /&gt;
&lt;br /&gt;
Of this implementation, also existing 25 tests are passing. We have also given each test their respective IDs within &amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt; as well so that they may be more easily identifiable. For more information about the previous testing plan, please refer to the previous implementation's page here: [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2484._Reimplement_participants_controller.rb]&lt;br /&gt;
&lt;br /&gt;
Below are any modifications to the existing test file (&amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt;) that we have made during the course of this project, alongside the descriptions and rationales behind them:&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
Below are the tests that are included in this implementation. We have updated the test descriptions to include more accurate and detailed information about each of the tests as well. Any tests that have been modified or new will be specified as such:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Retrieve participants by valid user ID (should return participant data)&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Retrieve participants by user ID with no participants (should return empty array)&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Retrieve participants with non-existent user ID (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Retrieve participants by user ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Retrieve participants by valid assignment ID (should return participant data)&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Retrieve participants by non-existent assignment ID (should return 'Assignment not found')&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Retrieve participants by assignment ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Retrieve a participant by valid ID (should return participant details)&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Retrieve a participant by non-existent ID (should return 'Not Found')&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Retrieve a participant by ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Delete a participant by valid ID (should return deletion success message)&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Delete a participant by non-existent ID (should return 'Not Found')&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Delete a participant by ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Update participant authorization with valid data (should return updated authorization)&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Update participant authorization with non-existent participant ID (should return 'Participant not found')&lt;br /&gt;
|-&lt;br /&gt;
| 16 || Update participant authorization with invalid role (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 17 || Update participant authorization with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 18 || Add a participant successfully (should return participant data with authorization)&lt;br /&gt;
|-&lt;br /&gt;
| 19 || Add a participant that already exists (should return duplicate participant error)&lt;br /&gt;
|-&lt;br /&gt;
| 20 || Add a participant with non-existent user ID (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 21 || Add a participant with non-existent assignment ID (should return 'Assignment not found')&lt;br /&gt;
|-&lt;br /&gt;
| 22 || Add a participant with invalid authorization (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 23 || Add a participant with unsupported authorization format (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 24 (NEW) || Add a participant missing user_id in request body (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 25 (NEW) || Add a participant missing assignment_id in request body (should return 'Assignment not found')&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Removed Tests==&lt;br /&gt;
&lt;br /&gt;
These are any tests that we have modified or removed from the previous testing plan. If the test ID is denoted by (Previously), that means that the ID shown was part of the previous implementation's testing plan.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Modification Description &lt;br /&gt;
|-&lt;br /&gt;
| (Previously) 22 || This test was removed as it was redundant. While it is important to check the authorization of the participant that would be invalid, the invalid ID used for this test is a duplicate of the previous test, meaning the result is guaranteed to match that of the previous test regardless of what is meant to be tested.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Next Steps=&lt;br /&gt;
&lt;br /&gt;
Being able to implement this could potentially simplify rendering to the view somewhat in that it could handle simple HTML status code handling. Below are some examples of implementations to serve as a point of reference:&lt;br /&gt;
&lt;br /&gt;
===Example 1===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# Checks if a target object (participant or participants) is not nil and then renders the object.&lt;br /&gt;
# If the object is nil, renders the object errors and sends a not_found_status and if the object&lt;br /&gt;
# exists, renders the object and sends a success status&lt;br /&gt;
# not_found_status default: :unprocessable_entity (422)&lt;br /&gt;
# success_status default: :ok (200)&lt;br /&gt;
def render_object_or_error(object, not_found_status: :unprocessable_entity, success_status: :ok)&lt;br /&gt;
  if object.nil?&lt;br /&gt;
    render json: { error: 'Resource not found' }, status: not_found_status&lt;br /&gt;
  elsif object.respond_to?(:errors) &amp;amp;&amp;amp; object.errors.any?&lt;br /&gt;
    render json: object.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: object, status: success_status&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example is modeled to be specific to the most common use case for this function in the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; by returning the default 422 and 200 error and success codes that are used by three instances of JSON rendering where it checks for whether a list of participants or a single participant is nil. These default values for the status codes are mainly to cover those instances, but could be changed to something else if necessary. The &amp;lt;code&amp;gt;object&amp;lt;/code&amp;gt; parameter is representative of the object that was meant to be rendered given the success or failure of the operation.&lt;br /&gt;
&lt;br /&gt;
===Example 2===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
def render_object_if(conditional, object, error_status, success_status)&lt;br /&gt;
  if conditional&lt;br /&gt;
    render json: { error: 'Resource not found' }, status: error_status&lt;br /&gt;
  else&lt;br /&gt;
    render json: object, status: success_status&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example is a more generic implementation of the function, mandating the error and success status codes rather than providing default values. The point of this was to emphasize readability when glancing over the use of this function. For example, being able to tell that seeing the function being used would immediately tell the reader what the success and failure states were immediately without having to find and inspect the function itself. The &amp;lt;code&amp;gt;conditional&amp;lt;/code&amp;gt; parameter would also allow the function to act similarly to a more readable ternary statement made for rendering.&lt;br /&gt;
&lt;br /&gt;
Implementing this successfully would reduce the amount of repetitive code being used within the controller, as the if-else view rendering is very common in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. We were unable to implement it within our given timeframe, so we opted to divert our focus on other, important tasks that we needed to do.&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Relevant Links =&lt;br /&gt;
&lt;br /&gt;
Pull Request [https://github.com/expertiza/reimplementation-back-end/pull/192] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=165284</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=165284"/>
		<updated>2025-04-27T19:41:12Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* filter_participants_by_assignment */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
==Video Overview==&lt;br /&gt;
&lt;br /&gt;
https://youtu.be/4kfz0hrmSg4&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; In the video it shows the test file at the end, but does not mention a last-minute change that numbers all of the tests to make it much easier to keep track of each of the tests and which ones are passing.&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Use of Large Language Models (LLMs)=&lt;br /&gt;
&lt;br /&gt;
For this project, we are using ChatGPT as an LLM helper in determining what issues there are within the code. The use of LLMs in this project will likely be limited to probing for potential issues that exist within the system.&lt;br /&gt;
&lt;br /&gt;
Below we have organized the following prompts and a summary of the output in a table:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 25%&amp;quot; | Prompts !! LLM Output Summary&lt;br /&gt;
|-&lt;br /&gt;
| [Code from &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;]&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt; Are there any ways where we can refactor the code to improve readability, DRYness, and clarity of error handling?&lt;br /&gt;
|| It recognized some of the issues we, as a team, had already identified and suggested fixes that were similar to what we outlined: &amp;lt;b&amp;gt;Redundant JSON Rendering Code&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_Redundant_JSON_Rendering_Code] and &amp;lt;b&amp;gt;Simplifying the Assignment of Participant Fields&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_the_Assignment_of_Participant_Fields]. Additionally, it suggested minor changes that we could implement, such as using &amp;lt;code&amp;gt;Participant.where(...)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; to filter out the code more efficiently instead of getting all database instances every time, as well as the use of strong parameters in &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update_authorization()&amp;lt;/code&amp;gt; to avoid having to implement custom parsing techniques. It also recommends renaming the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; function to something more specific in relation to its purpose (adding a &amp;lt;code&amp;gt;Participant&amp;lt;/code&amp;gt; to an &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Potential Redundant Tests in &amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|| The tests on line 222 and 231 are redundant as only the authorization differs. (Note: This should be investigated to see whether or not this is necessary)&lt;br /&gt;
|-&lt;br /&gt;
| Checking for issues with the current testing files&lt;br /&gt;
|| The &amp;quot;Get Participant by ID call&amp;quot; test was returning a 201 status code instead of the more suitable 200 code&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed information on what prompts we used and the output we got, please visit the page here: [https://docs.google.com/document/d/105_U_Coky-edx7n-tFhD2B5RqmVXxEsKPW_qUaf7bQU/edit?usp=sharing].&lt;br /&gt;
&lt;br /&gt;
=Requirements=&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Some API functions are not returning the correct HTML status messages (e.g. test on line 136 returns 201 instead of 200)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Documentation and comments can be somewhat vague&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;In-line comments should be more descriptive, explaining what the code does in more details&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Tests are not described via comments, but in name alone; some more descriptive comments that explain the tests in more detail would be ideal&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Design / Proposed Solution=&lt;br /&gt;
&lt;br /&gt;
Based on the previous implementation's controller diagram, we have created a new version that contains our proposed changes and modifications to &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[File:Participants_controller_refactor_v1.2.png]]&lt;br /&gt;
&lt;br /&gt;
==Simplifying Redundant JSON Rendering Code==&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Simplifying the Assignment of Participant Fields==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update()&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Provide More Clarity in Function Names==&lt;br /&gt;
&lt;br /&gt;
There are some functions that are somewhat unclear/vague in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. For example, the &amp;lt;code&amp;gt;list_user_participants()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== - Suggested Method Name Improvements ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Old Method Name&lt;br /&gt;
! New Method Name&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Clearer and more descriptive&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Clearer and more descriptive and is consistent with the other get method&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;&lt;br /&gt;
| Describes both creation and authorization setup of participant to assignment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_user_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt;&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_assignment_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Improve Documentation and Comments==&lt;br /&gt;
&lt;br /&gt;
Some of the documentation and in-line comments can be somewhat vague. This can lead to misconceptions about how some functions work or how some of the code can function. Below are potential improvements we plan to make for function descriptions, though these may change with the final implementation.&lt;br /&gt;
&lt;br /&gt;
=== Improved Method Comments ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Original Comment&lt;br /&gt;
! Refactored Comment&lt;br /&gt;
|-&lt;br /&gt;
| render_participants_by_user_id&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
| Retrieves all participants associated with the specified user ID&lt;br /&gt;
|-&lt;br /&gt;
| render_participants_by_assignment_id&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
| Retrieves all participants linked to the specified assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
| Fetch and return the participant with the given ID&lt;br /&gt;
|-&lt;br /&gt;
| add_participant_to_assignment&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
| Creates a new participant for a given assignment and assigns appropriate authorization and permissions&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
| Updates the participant’s authorization role and related permissions&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
| Deletes the participant identified by the given ID and returns a confirmation message&lt;br /&gt;
|-&lt;br /&gt;
| participant_params&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
| Strong parameters: list of attributes allowed for participant creation or update&lt;br /&gt;
|-&lt;br /&gt;
| filter_participants_by_user&lt;br /&gt;
| Filters participants based on the provided user. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by user, if provided&lt;br /&gt;
|-&lt;br /&gt;
| filter_participants_by_assignment&lt;br /&gt;
| Filters participants based on the provided assignment. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by assignment, if provided&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| Validates that the authorization parameter is present and is one of the following valid authorizations: reader, reviewer, submitter, mentor&lt;br /&gt;
| Ensures authorization param is valid and returns it in lowercase; otherwise returns error response&lt;br /&gt;
|-&lt;br /&gt;
| find_user / find_assignment / find_participant&lt;br /&gt;
| Finds a user/assignment/participant by ID and returns it&lt;br /&gt;
| Fetches the corresponding record by ID; renders a not-found error if record does not exist&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Proposed Testing Changes==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add more descriptive comments for tests&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that authorizations are updated correctly&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that inputted path parameters are not missing and valid inputs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Tests at Line 222 and Line 231 are redundant, as the only difference in the test is the authorization, which would not affect what happens if a participant is not found&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
As this is a refactoring project, most of our work on the codebase involved cleaning up the current codebase to better align with foundational code style principles rather than introducing any of kind of new functionality. Our primary focus is to make the code more readable and easier to work with than before. We also took the liberty of fixing some minor errors that we found along the way.&lt;br /&gt;
&lt;br /&gt;
==Changelog==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Naming changes to multiple functions for better clarity and consistency&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Changed HTML status message for &amp;lt;code&amp;gt;show()&amp;lt;/code&amp;gt; from 201 (Created) to 200 (OK) as it is a better fit&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Created the &amp;lt;code&amp;gt;assign_participant_permissions()&amp;lt;/code&amp;gt; method&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Introduced two additional tests and removed a redundant one (see Testing Plan for more details)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Removed redundant queries to &amp;lt;code&amp;gt;Participant.all()&amp;lt;/code&amp;gt; in both filtering methods&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Updated method comments to be more descriptive (see comments table in Design)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Function Name Changes==&lt;br /&gt;
&lt;br /&gt;
The previous implementation had several functions that were strangely named or had names that could be easily misconstrued. The name changes remain the same from the proposal and design section, but for the purpose of clarity, the rationale for each of the functions will be provided below.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
These two functions are meant to render a list of participants given a &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt; respectively. Based on the name alone, it is difficult to tell that the function would render a User/Assignment or Participants. In order to remedy this, we chose the names &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;. The word &amp;quot;list&amp;quot; was replaced by &amp;quot;render&amp;quot; in order to better denote that it is rendering something (json in this case) and the &amp;quot;by&amp;quot; is added to emphasize that the User and Assignment are being used as parameters to search for the Participants. This provides a much clearer picture of what these functions should do compared to before.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; function's name was too vague to be particularly useful in identifying its purpose. To be more accurate, the function was meant to add the user to a given assignment, which would return a participant from the assignment's &amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; function. The new name of the function provides much more context to what it does (&amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_user_participants&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_assignment_participants&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Similar to the list methods that were previously mentioned, it is difficult to tell what exactly these two functions do. While it can be easily seen that it filters something, what is being filtered can be easily mistaken (e.g. does it filter users by participants or participants by users?). The new names, &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt; are much clearer in defining that the User and Assignment are being used as the filter parameters for the function.&lt;br /&gt;
&lt;br /&gt;
==HTML Status Code Change for &amp;lt;code&amp;gt;GET&amp;lt;/code&amp;gt; Call==&lt;br /&gt;
&lt;br /&gt;
The status code being used for this was previously 201, denoting &amp;quot;successful creation&amp;quot;. We have corrected this to a simple 200 code, which signifies an &amp;quot;ok&amp;quot; status message. This issue was actually identified by ChatGPT while we were dowsing for potential issues.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Test modified&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# Tests whether a participant returns properly if provided with a valid Participant ID&lt;br /&gt;
response '200', 'Returns a participant' do&lt;br /&gt;
  let(:id) { participant2.id }&lt;br /&gt;
&lt;br /&gt;
  run_test! do |response|&lt;br /&gt;
    data = JSON.parse(response.body)&lt;br /&gt;
    expect(data['user_id']).to eq(studenta.id)&lt;br /&gt;
    expect(data['assignment_id']).to eq(assignment2.id)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Redundant &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; Queries Removed==&lt;br /&gt;
&lt;br /&gt;
This issue was initially caught by the LLM, ChatGPT, that the team was using in order to find potential issues. We found that simply using &amp;lt;code&amp;gt;Participant.where()&amp;lt;/code&amp;gt; removed the need for the &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; query entirely while changing nothing else about the function, reducing the amount of queries necessary to call the filtering methods, &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# New function&lt;br /&gt;
def filter_participants_by_user(user)&lt;br /&gt;
  participants = Participant.where(user_id: user.id) if user # This would simply get the participants given the proper user ID&lt;br /&gt;
  participants.order(:id)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# Old function&lt;br /&gt;
def filter_participants_by_user(user)&lt;br /&gt;
  participants = Participant.all() # This would obtain the entire list of participants rather than just the necessary ones&lt;br /&gt;
  participants = participants.where(user_id: user.id) if user&lt;br /&gt;
  participants.order(:id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==New Private Method: &amp;lt;code&amp;gt;assign_participant_permissions()&amp;lt;/code&amp;gt;==&lt;br /&gt;
&lt;br /&gt;
The reasoning behind the addition of this method is because of a repeated piece of code that existed in the previous implementation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
participant.authorization = authorization&lt;br /&gt;
participant.can_submit = permissions[:can_submit]&lt;br /&gt;
participant.can_review = permissions[:can_review]&lt;br /&gt;
participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This was repeated in two different contexts: when the Participant was updated or created. This is a violation of the DRY principle, as the same code is repeated multiple times where it could have been reduced to make it more easily readable. In order to resolve this issue, we simply turned this code snippet into a private method that can be called within &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  # An authorization string containing the participant's role is taken and used to determine&lt;br /&gt;
  # what permissions will be allocated to the participant. Each of these permissions will&lt;br /&gt;
  # then be assigned to the Participant's database permission attributes.&lt;br /&gt;
  #&lt;br /&gt;
  # @param [String] authorization: An authorization string that represents the participant's role&lt;br /&gt;
  # @param [Participant] participant: The participant whose authorization permissions are being updated&lt;br /&gt;
  def assign_participant_permissions(authorization, participant)&lt;br /&gt;
    # Call helper method from participants_helper to retrieve a dictionary containing the&lt;br /&gt;
    # appropriate permission boolean values for the role specified by the authorization string&lt;br /&gt;
    permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
    # Assigns each of the boolean permission values to their respective database counterparts&lt;br /&gt;
    participant.authorization = authorization&lt;br /&gt;
    participant.can_submit = permissions[:can_submit]&lt;br /&gt;
    participant.can_review = permissions[:can_review]&lt;br /&gt;
    participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
    participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Description:===&lt;br /&gt;
&lt;br /&gt;
An authorization string containing the participant's role is taken and used to determine what permissions will be allocated to the participant. Each of these permissions will then be assigned to the Participant's database permission attributes.&lt;br /&gt;
&lt;br /&gt;
===Parameters:===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt;: An authorization string that represents the participant's role. This can be either reader, reviewer, submitter, or mentor.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant&amp;lt;/code&amp;gt;: The participant whose attributes are being updated. This is passed in to be modified by the function to be used to assign each of the participant's attribute values that are representative of its assigned role.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Behavior===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Use &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;participants_helper&amp;lt;/code&amp;gt; in order to get all necessary permission boolean values for a given participant role&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Assign each of the permission boolean values (&amp;lt;code&amp;gt;can_submit&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_review&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_take_quiz&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_mentor&amp;lt;/code&amp;gt;)&amp;lt;/li&amp;gt; from the helper method to their respective database attribute counterparts in Participant&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Post-Demo Changes==&lt;br /&gt;
&lt;br /&gt;
There were three notable topics that were brought up during the final demo presentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The renaming of &amp;lt;code&amp;gt;get_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;get_participants_by_assignment&amp;lt;/code&amp;gt; to something more suitable to its purpose in rendering the JSON of a list of participants&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Consider the application of &amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; within &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Update the wiki to provide descriptions for each of the methods included in &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt; (See Methods subsection in the Implementation section)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Renaming &amp;lt;code&amp;gt;get_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;get_participants_by_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
These two functions were renamed (once again) to something that better fit the functionality and purpose of the function. Since these functions are meant to render the lists of participants gotten from their respective parameters and use the ID values for each, both of the functions were renamed to &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt; respectively. The renaming of the filter methods was also brought up, but those functions actually do use the objects themselves as parameters, so have been left as is for the time being.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; within &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
We reconsidered the use of these methods within the controller since it was somewhat odd that it would have these methods. However, we concluded that, since the find methods are helper methods that are private and not open to be used by other parts of the code, to be fine to leave as is. This is mostly because they are simple helper methods that get the current user and assignment and return them, rendering an error if they do not exist.&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches all participants associated with the specified user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;user_id [Integer]&amp;lt;/code&amp;gt;: ID of the user&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; A JSON array of participant objects&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized for the action&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If the user does not exist&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If the query fails unexpectedly&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Renamed from &amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def render_participants_by_user_id&lt;br /&gt;
    user = find_user if params[:user_id].present?&lt;br /&gt;
    return if params[:user_id].present? &amp;amp;&amp;amp; user.nil?&lt;br /&gt;
&lt;br /&gt;
    participants = filter_participants_by_user(user)&lt;br /&gt;
&lt;br /&gt;
    if participants.nil?&lt;br /&gt;
      render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participants, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Fetches all participants associated with a specific assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment_id [Integer]&amp;lt;/code&amp;gt;: ID of the assignment&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; A JSON array of participant objects&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized for the action&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If the assignment does not exist&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If the query fails unexpectedly&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Renamed from &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def render_participants_by_assignment_id&lt;br /&gt;
    assignment = find_assignment if params[:assignment_id].present?&lt;br /&gt;
    return if params[:assignment_id].present? &amp;amp;&amp;amp; assignment.nil?&lt;br /&gt;
&lt;br /&gt;
    participants = filter_participants_by_assignment(assignment)&lt;br /&gt;
&lt;br /&gt;
    if participants.nil?&lt;br /&gt;
      render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participants, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;show&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches the details of a specific participant by their ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; JSON representation of the participant&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If the participant does not exist&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If the lookup fails&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Standardized participant lookup to return proper HTTP codes&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def show&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if participant.nil?&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adds a user as a participant to an assignment with the specified authorization (role and permissions).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant[user_id] [Integer]&amp;lt;/code&amp;gt;: ID of the user&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant[assignment_id] [Integer]&amp;lt;/code&amp;gt;: ID of the assignment&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: Role assigned to the participant (reader, reviewer, submitter, mentor)&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;201 Created:&amp;lt;/b&amp;gt; Participant successfully added&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If user or assignment is not found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If authorization is invalid or save fails&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Introduced role-based permission assignment during participant creation&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def add_participant_to_assignment&lt;br /&gt;
    user = find_user&lt;br /&gt;
    return unless user&lt;br /&gt;
&lt;br /&gt;
    assignment = find_assignment&lt;br /&gt;
    return unless assignment&lt;br /&gt;
&lt;br /&gt;
    authorization = validate_authorization&lt;br /&gt;
    return unless authorization&lt;br /&gt;
&lt;br /&gt;
    participant = assignment.add_participant(user)&lt;br /&gt;
    assign_participant_permissions(authorization, participant)&lt;br /&gt;
&lt;br /&gt;
    if participant.save&lt;br /&gt;
      render json: participant, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;update_authorization&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Updates the authorization (role) of an existing participant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: New role to assign (reader, reviewer, submitter, mentor)&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;201 Created:&amp;lt;/b&amp;gt; Authorization updated successfully&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If participant is not found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If authorization is invalid&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Added validation for authorization role values&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = find_participant&lt;br /&gt;
    return unless participant&lt;br /&gt;
&lt;br /&gt;
    authorization = validate_authorization&lt;br /&gt;
    return unless authorization&lt;br /&gt;
&lt;br /&gt;
    assign_participant_permissions(authorization, participant)&lt;br /&gt;
&lt;br /&gt;
    if participant.save&lt;br /&gt;
      render json: participant, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;destroy&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deletes a participant from the system. Optionally includes assignment and team context in the success message.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment_id [Integer] (optional)&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;team_id [Integer] (optional)&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; Success message indicating deletion&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If participant is not found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If deletion fails&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Enhanced success message based on team/assignment presence&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def destroy&lt;br /&gt;
    participant = Participant.find_by(id: params[:id])&lt;br /&gt;
  &lt;br /&gt;
    if participant.nil?&lt;br /&gt;
      render json: { error: 'Not Found' }, status: :not_found&lt;br /&gt;
    elsif participant.destroy&lt;br /&gt;
      successful_deletion_message = if params[:team_id].nil?&lt;br /&gt;
                                      &amp;quot;Participant #{params[:id]} in Assignment #{params[:assignment_id]} has been deleted successfully!&amp;quot;&lt;br /&gt;
                                    else&lt;br /&gt;
                                      &amp;quot;Participant #{params[:id]} in Team #{params[:team_id]} of Assignment #{params[:assignment_id]} has been deleted successfully!&amp;quot;&lt;br /&gt;
                                    end&lt;br /&gt;
      render json: { message: successful_deletion_message }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;participants_params&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Defines the strong parameters allowed when creating or updating a participant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant&amp;lt;/code&amp;gt;: Hash containing fields like user_id, assignment_id, authorization, etc.&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Permitted parameter hash for participant creation/update&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Updated to include all permission and assignment-related fields&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def participant_params&lt;br /&gt;
    params.require(:participant).permit(:user_id, :assignment_id, :authorization, :can_submit,&lt;br /&gt;
                                        :can_review, :can_take_quiz, :can_mentor, :handle,&lt;br /&gt;
                                        :team_id, :join_team_request_id, :permission_granted,&lt;br /&gt;
                                        :topic, :current_stage, :stage_deadline)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches participants associated with a given user, ordered by ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;user [User]&amp;lt;/code&amp;gt;: User object&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Ordered list of participants for the user&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;None&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def filter_participants_by_user(user)&lt;br /&gt;
    participants = Participant.where(user_id: user.id) if user&lt;br /&gt;
    participants.order(:id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches participants associated with a given assignment, ordered by ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment [Assignment]&amp;lt;/code&amp;gt;: Assignment object&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Ordered list of participants for the assignment&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def filter_participants_by_assignment(assignment)&lt;br /&gt;
    participants = Participant.where(assignment_id: assignment.id) if assignment&lt;br /&gt;
    participants.order(:id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finds a user based on the provided user_id.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;user_id [Integer]&amp;lt;/code&amp;gt;: ID of the user&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;User object if found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;404 error if not found&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Centralized user lookup and error handling&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_user&lt;br /&gt;
    user_id = params[:user_id]&lt;br /&gt;
    user = User.find_by(id: user_id)&lt;br /&gt;
    render json: { error: 'User not found' }, status: :not_found unless user&lt;br /&gt;
    user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finds an assignment based on the provided assignment_id.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment_id [Integer]&amp;lt;/code&amp;gt;: ID of the assignment&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Assignment object if found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;404 error if not found&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Centralized assignment lookup and error handling&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_assignment&lt;br /&gt;
    assignment_id = params[:assignment_id]&lt;br /&gt;
    assignment = Assignment.find_by(id: assignment_id)&lt;br /&gt;
    render json: { error: 'Assignment not found' }, status: :not_found unless assignment&lt;br /&gt;
    assignment&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&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;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finds a participant based on the provided ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Participant object if found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;404 error if not found&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Centralized participant lookup and error handling&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_participant&lt;br /&gt;
    participant_id = params[:id]&lt;br /&gt;
    participant = Participant.find_by(id: participant_id)&lt;br /&gt;
    render json: { error: 'Participant not found' }, status: :not_found unless participant&lt;br /&gt;
    participant&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;assign_participant_permissions&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Assigns permission flags to a participant based on the authorization role provided.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: Role to assign&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant [Participant]&amp;lt;/code&amp;gt;: Participant object&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Participant object with updated permissions&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Added dynamic permission setting based on role&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def assign_participant_permissions(authorization, participant)&lt;br /&gt;
    # Call helper method from participants_helper to retrieve a dictionary containing the&lt;br /&gt;
    # appropriate permission boolean values for the role specified by the authorization string&lt;br /&gt;
    permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
    # Assigns each of the boolean permission values to their respective database counterparts&lt;br /&gt;
    participant.authorization = authorization&lt;br /&gt;
    participant.can_submit = permissions[:can_submit]&lt;br /&gt;
    participant.can_review = permissions[:can_review]&lt;br /&gt;
    participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
    participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;validate_authorization&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Validates that the authorization string is present and one of the accepted roles.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: Authorization role&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Validated authorization string&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;422 error if invalid&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Standardized authorization validation across endpoints&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def validate_authorization&lt;br /&gt;
    valid_authorizations = %w[reader reviewer submitter mentor]&lt;br /&gt;
    authorization = params[:authorization]&lt;br /&gt;
    authorization = authorization.downcase if authorization.present?&lt;br /&gt;
&lt;br /&gt;
    unless authorization&lt;br /&gt;
      render json: { error: 'authorization is required' }, status: :unprocessable_entity&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    unless valid_authorizations.include?(authorization)&lt;br /&gt;
      render json: { error: 'authorization not valid. Valid authorizations are: Reader, Reviewer, Submitter, Mentor' },&lt;br /&gt;
             status: :unprocessable_entity&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    authorization&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Testing Plan=&lt;br /&gt;
&lt;br /&gt;
Of this implementation, also existing 25 tests are passing. We have also given each test their respective IDs within &amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt; as well so that they may be more easily identifiable. For more information about the previous testing plan, please refer to the previous implementation's page here: [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2484._Reimplement_participants_controller.rb]&lt;br /&gt;
&lt;br /&gt;
Below are any modifications to the existing test file (&amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt;) that we have made during the course of this project, alongside the descriptions and rationales behind them:&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
Below are the tests that are included in this implementation. We have updated the test descriptions to include more accurate and detailed information about each of the tests as well. Any tests that have been modified or new will be specified as such:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Retrieve participants by valid user ID (should return participant data)&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Retrieve participants by user ID with no participants (should return empty array)&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Retrieve participants with non-existent user ID (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Retrieve participants by user ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Retrieve participants by valid assignment ID (should return participant data)&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Retrieve participants by non-existent assignment ID (should return 'Assignment not found')&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Retrieve participants by assignment ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Retrieve a participant by valid ID (should return participant details)&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Retrieve a participant by non-existent ID (should return 'Not Found')&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Retrieve a participant by ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Delete a participant by valid ID (should return deletion success message)&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Delete a participant by non-existent ID (should return 'Not Found')&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Delete a participant by ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Update participant authorization with valid data (should return updated authorization)&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Update participant authorization with non-existent participant ID (should return 'Participant not found')&lt;br /&gt;
|-&lt;br /&gt;
| 16 || Update participant authorization with invalid role (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 17 || Update participant authorization with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 18 || Add a participant successfully (should return participant data with authorization)&lt;br /&gt;
|-&lt;br /&gt;
| 19 || Add a participant that already exists (should return duplicate participant error)&lt;br /&gt;
|-&lt;br /&gt;
| 20 || Add a participant with non-existent user ID (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 21 || Add a participant with non-existent assignment ID (should return 'Assignment not found')&lt;br /&gt;
|-&lt;br /&gt;
| 22 || Add a participant with invalid authorization (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 23 || Add a participant with unsupported authorization format (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 24 (NEW) || Add a participant missing user_id in request body (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 25 (NEW) || Add a participant missing assignment_id in request body (should return 'Assignment not found')&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Removed Tests==&lt;br /&gt;
&lt;br /&gt;
These are any tests that we have modified or removed from the previous testing plan. If the test ID is denoted by (Previously), that means that the ID shown was part of the previous implementation's testing plan.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Modification Description &lt;br /&gt;
|-&lt;br /&gt;
| (Previously) 22 || This test was removed as it was redundant. While it is important to check the authorization of the participant that would be invalid, the invalid ID used for this test is a duplicate of the previous test, meaning the result is guaranteed to match that of the previous test regardless of what is meant to be tested.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Next Steps=&lt;br /&gt;
&lt;br /&gt;
Being able to implement this could potentially simplify rendering to the view somewhat in that it could handle simple HTML status code handling. Below are some examples of implementations to serve as a point of reference:&lt;br /&gt;
&lt;br /&gt;
===Example 1===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# Checks if a target object (participant or participants) is not nil and then renders the object.&lt;br /&gt;
# If the object is nil, renders the object errors and sends a not_found_status and if the object&lt;br /&gt;
# exists, renders the object and sends a success status&lt;br /&gt;
# not_found_status default: :unprocessable_entity (422)&lt;br /&gt;
# success_status default: :ok (200)&lt;br /&gt;
def render_object_or_error(object, not_found_status: :unprocessable_entity, success_status: :ok)&lt;br /&gt;
  if object.nil?&lt;br /&gt;
    render json: { error: 'Resource not found' }, status: not_found_status&lt;br /&gt;
  elsif object.respond_to?(:errors) &amp;amp;&amp;amp; object.errors.any?&lt;br /&gt;
    render json: object.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: object, status: success_status&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example is modeled to be specific to the most common use case for this function in the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; by returning the default 422 and 200 error and success codes that are used by three instances of JSON rendering where it checks for whether a list of participants or a single participant is nil. These default values for the status codes are mainly to cover those instances, but could be changed to something else if necessary. The &amp;lt;code&amp;gt;object&amp;lt;/code&amp;gt; parameter is representative of the object that was meant to be rendered given the success or failure of the operation.&lt;br /&gt;
&lt;br /&gt;
===Example 2===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
def render_object_if(conditional, object, error_status, success_status)&lt;br /&gt;
  if conditional&lt;br /&gt;
    render json: { error: 'Resource not found' }, status: error_status&lt;br /&gt;
  else&lt;br /&gt;
    render json: object, status: success_status&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example is a more generic implementation of the function, mandating the error and success status codes rather than providing default values. The point of this was to emphasize readability when glancing over the use of this function. For example, being able to tell that seeing the function being used would immediately tell the reader what the success and failure states were immediately without having to find and inspect the function itself. The &amp;lt;code&amp;gt;conditional&amp;lt;/code&amp;gt; parameter would also allow the function to act similarly to a more readable ternary statement made for rendering.&lt;br /&gt;
&lt;br /&gt;
Implementing this successfully would reduce the amount of repetitive code being used within the controller, as the if-else view rendering is very common in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. We were unable to implement it within our given timeframe, so we opted to divert our focus on other, important tasks that we needed to do.&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Relevant Links =&lt;br /&gt;
&lt;br /&gt;
Pull Request [https://github.com/expertiza/reimplementation-back-end/pull/192] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=165283</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=165283"/>
		<updated>2025-04-27T19:32:37Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Methods (TEMP) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
==Video Overview==&lt;br /&gt;
&lt;br /&gt;
https://youtu.be/4kfz0hrmSg4&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; In the video it shows the test file at the end, but does not mention a last-minute change that numbers all of the tests to make it much easier to keep track of each of the tests and which ones are passing.&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Use of Large Language Models (LLMs)=&lt;br /&gt;
&lt;br /&gt;
For this project, we are using ChatGPT as an LLM helper in determining what issues there are within the code. The use of LLMs in this project will likely be limited to probing for potential issues that exist within the system.&lt;br /&gt;
&lt;br /&gt;
Below we have organized the following prompts and a summary of the output in a table:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 25%&amp;quot; | Prompts !! LLM Output Summary&lt;br /&gt;
|-&lt;br /&gt;
| [Code from &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;]&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt; Are there any ways where we can refactor the code to improve readability, DRYness, and clarity of error handling?&lt;br /&gt;
|| It recognized some of the issues we, as a team, had already identified and suggested fixes that were similar to what we outlined: &amp;lt;b&amp;gt;Redundant JSON Rendering Code&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_Redundant_JSON_Rendering_Code] and &amp;lt;b&amp;gt;Simplifying the Assignment of Participant Fields&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_the_Assignment_of_Participant_Fields]. Additionally, it suggested minor changes that we could implement, such as using &amp;lt;code&amp;gt;Participant.where(...)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; to filter out the code more efficiently instead of getting all database instances every time, as well as the use of strong parameters in &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update_authorization()&amp;lt;/code&amp;gt; to avoid having to implement custom parsing techniques. It also recommends renaming the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; function to something more specific in relation to its purpose (adding a &amp;lt;code&amp;gt;Participant&amp;lt;/code&amp;gt; to an &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Potential Redundant Tests in &amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|| The tests on line 222 and 231 are redundant as only the authorization differs. (Note: This should be investigated to see whether or not this is necessary)&lt;br /&gt;
|-&lt;br /&gt;
| Checking for issues with the current testing files&lt;br /&gt;
|| The &amp;quot;Get Participant by ID call&amp;quot; test was returning a 201 status code instead of the more suitable 200 code&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed information on what prompts we used and the output we got, please visit the page here: [https://docs.google.com/document/d/105_U_Coky-edx7n-tFhD2B5RqmVXxEsKPW_qUaf7bQU/edit?usp=sharing].&lt;br /&gt;
&lt;br /&gt;
=Requirements=&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Some API functions are not returning the correct HTML status messages (e.g. test on line 136 returns 201 instead of 200)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Documentation and comments can be somewhat vague&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;In-line comments should be more descriptive, explaining what the code does in more details&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Tests are not described via comments, but in name alone; some more descriptive comments that explain the tests in more detail would be ideal&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Design / Proposed Solution=&lt;br /&gt;
&lt;br /&gt;
Based on the previous implementation's controller diagram, we have created a new version that contains our proposed changes and modifications to &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[File:Participants_controller_refactor_v1.2.png]]&lt;br /&gt;
&lt;br /&gt;
==Simplifying Redundant JSON Rendering Code==&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Simplifying the Assignment of Participant Fields==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update()&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Provide More Clarity in Function Names==&lt;br /&gt;
&lt;br /&gt;
There are some functions that are somewhat unclear/vague in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. For example, the &amp;lt;code&amp;gt;list_user_participants()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== - Suggested Method Name Improvements ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Old Method Name&lt;br /&gt;
! New Method Name&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Clearer and more descriptive&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Clearer and more descriptive and is consistent with the other get method&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;&lt;br /&gt;
| Describes both creation and authorization setup of participant to assignment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_user_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt;&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_assignment_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Improve Documentation and Comments==&lt;br /&gt;
&lt;br /&gt;
Some of the documentation and in-line comments can be somewhat vague. This can lead to misconceptions about how some functions work or how some of the code can function. Below are potential improvements we plan to make for function descriptions, though these may change with the final implementation.&lt;br /&gt;
&lt;br /&gt;
=== Improved Method Comments ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Original Comment&lt;br /&gt;
! Refactored Comment&lt;br /&gt;
|-&lt;br /&gt;
| render_participants_by_user_id&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
| Retrieves all participants associated with the specified user ID&lt;br /&gt;
|-&lt;br /&gt;
| render_participants_by_assignment_id&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
| Retrieves all participants linked to the specified assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
| Fetch and return the participant with the given ID&lt;br /&gt;
|-&lt;br /&gt;
| add_participant_to_assignment&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
| Creates a new participant for a given assignment and assigns appropriate authorization and permissions&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
| Updates the participant’s authorization role and related permissions&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
| Deletes the participant identified by the given ID and returns a confirmation message&lt;br /&gt;
|-&lt;br /&gt;
| participant_params&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
| Strong parameters: list of attributes allowed for participant creation or update&lt;br /&gt;
|-&lt;br /&gt;
| filter_participants_by_user&lt;br /&gt;
| Filters participants based on the provided user. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by user, if provided&lt;br /&gt;
|-&lt;br /&gt;
| filter_participants_by_assignment&lt;br /&gt;
| Filters participants based on the provided assignment. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by assignment, if provided&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| Validates that the authorization parameter is present and is one of the following valid authorizations: reader, reviewer, submitter, mentor&lt;br /&gt;
| Ensures authorization param is valid and returns it in lowercase; otherwise returns error response&lt;br /&gt;
|-&lt;br /&gt;
| find_user / find_assignment / find_participant&lt;br /&gt;
| Finds a user/assignment/participant by ID and returns it&lt;br /&gt;
| Fetches the corresponding record by ID; renders a not-found error if record does not exist&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Proposed Testing Changes==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add more descriptive comments for tests&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that authorizations are updated correctly&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that inputted path parameters are not missing and valid inputs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Tests at Line 222 and Line 231 are redundant, as the only difference in the test is the authorization, which would not affect what happens if a participant is not found&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
As this is a refactoring project, most of our work on the codebase involved cleaning up the current codebase to better align with foundational code style principles rather than introducing any of kind of new functionality. Our primary focus is to make the code more readable and easier to work with than before. We also took the liberty of fixing some minor errors that we found along the way.&lt;br /&gt;
&lt;br /&gt;
==Changelog==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Naming changes to multiple functions for better clarity and consistency&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Changed HTML status message for &amp;lt;code&amp;gt;show()&amp;lt;/code&amp;gt; from 201 (Created) to 200 (OK) as it is a better fit&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Created the &amp;lt;code&amp;gt;assign_participant_permissions()&amp;lt;/code&amp;gt; method&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Introduced two additional tests and removed a redundant one (see Testing Plan for more details)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Removed redundant queries to &amp;lt;code&amp;gt;Participant.all()&amp;lt;/code&amp;gt; in both filtering methods&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Updated method comments to be more descriptive (see comments table in Design)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Function Name Changes==&lt;br /&gt;
&lt;br /&gt;
The previous implementation had several functions that were strangely named or had names that could be easily misconstrued. The name changes remain the same from the proposal and design section, but for the purpose of clarity, the rationale for each of the functions will be provided below.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
These two functions are meant to render a list of participants given a &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt; respectively. Based on the name alone, it is difficult to tell that the function would render a User/Assignment or Participants. In order to remedy this, we chose the names &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;. The word &amp;quot;list&amp;quot; was replaced by &amp;quot;render&amp;quot; in order to better denote that it is rendering something (json in this case) and the &amp;quot;by&amp;quot; is added to emphasize that the User and Assignment are being used as parameters to search for the Participants. This provides a much clearer picture of what these functions should do compared to before.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; function's name was too vague to be particularly useful in identifying its purpose. To be more accurate, the function was meant to add the user to a given assignment, which would return a participant from the assignment's &amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; function. The new name of the function provides much more context to what it does (&amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_user_participants&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_assignment_participants&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Similar to the list methods that were previously mentioned, it is difficult to tell what exactly these two functions do. While it can be easily seen that it filters something, what is being filtered can be easily mistaken (e.g. does it filter users by participants or participants by users?). The new names, &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt; are much clearer in defining that the User and Assignment are being used as the filter parameters for the function.&lt;br /&gt;
&lt;br /&gt;
==HTML Status Code Change for &amp;lt;code&amp;gt;GET&amp;lt;/code&amp;gt; Call==&lt;br /&gt;
&lt;br /&gt;
The status code being used for this was previously 201, denoting &amp;quot;successful creation&amp;quot;. We have corrected this to a simple 200 code, which signifies an &amp;quot;ok&amp;quot; status message. This issue was actually identified by ChatGPT while we were dowsing for potential issues.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Test modified&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# Tests whether a participant returns properly if provided with a valid Participant ID&lt;br /&gt;
response '200', 'Returns a participant' do&lt;br /&gt;
  let(:id) { participant2.id }&lt;br /&gt;
&lt;br /&gt;
  run_test! do |response|&lt;br /&gt;
    data = JSON.parse(response.body)&lt;br /&gt;
    expect(data['user_id']).to eq(studenta.id)&lt;br /&gt;
    expect(data['assignment_id']).to eq(assignment2.id)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Redundant &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; Queries Removed==&lt;br /&gt;
&lt;br /&gt;
This issue was initially caught by the LLM, ChatGPT, that the team was using in order to find potential issues. We found that simply using &amp;lt;code&amp;gt;Participant.where()&amp;lt;/code&amp;gt; removed the need for the &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; query entirely while changing nothing else about the function, reducing the amount of queries necessary to call the filtering methods, &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# New function&lt;br /&gt;
def filter_participants_by_user(user)&lt;br /&gt;
  participants = Participant.where(user_id: user.id) if user # This would simply get the participants given the proper user ID&lt;br /&gt;
  participants.order(:id)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# Old function&lt;br /&gt;
def filter_participants_by_user(user)&lt;br /&gt;
  participants = Participant.all() # This would obtain the entire list of participants rather than just the necessary ones&lt;br /&gt;
  participants = participants.where(user_id: user.id) if user&lt;br /&gt;
  participants.order(:id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==New Private Method: &amp;lt;code&amp;gt;assign_participant_permissions()&amp;lt;/code&amp;gt;==&lt;br /&gt;
&lt;br /&gt;
The reasoning behind the addition of this method is because of a repeated piece of code that existed in the previous implementation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
participant.authorization = authorization&lt;br /&gt;
participant.can_submit = permissions[:can_submit]&lt;br /&gt;
participant.can_review = permissions[:can_review]&lt;br /&gt;
participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This was repeated in two different contexts: when the Participant was updated or created. This is a violation of the DRY principle, as the same code is repeated multiple times where it could have been reduced to make it more easily readable. In order to resolve this issue, we simply turned this code snippet into a private method that can be called within &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  # An authorization string containing the participant's role is taken and used to determine&lt;br /&gt;
  # what permissions will be allocated to the participant. Each of these permissions will&lt;br /&gt;
  # then be assigned to the Participant's database permission attributes.&lt;br /&gt;
  #&lt;br /&gt;
  # @param [String] authorization: An authorization string that represents the participant's role&lt;br /&gt;
  # @param [Participant] participant: The participant whose authorization permissions are being updated&lt;br /&gt;
  def assign_participant_permissions(authorization, participant)&lt;br /&gt;
    # Call helper method from participants_helper to retrieve a dictionary containing the&lt;br /&gt;
    # appropriate permission boolean values for the role specified by the authorization string&lt;br /&gt;
    permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
    # Assigns each of the boolean permission values to their respective database counterparts&lt;br /&gt;
    participant.authorization = authorization&lt;br /&gt;
    participant.can_submit = permissions[:can_submit]&lt;br /&gt;
    participant.can_review = permissions[:can_review]&lt;br /&gt;
    participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
    participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Description:===&lt;br /&gt;
&lt;br /&gt;
An authorization string containing the participant's role is taken and used to determine what permissions will be allocated to the participant. Each of these permissions will then be assigned to the Participant's database permission attributes.&lt;br /&gt;
&lt;br /&gt;
===Parameters:===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt;: An authorization string that represents the participant's role. This can be either reader, reviewer, submitter, or mentor.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant&amp;lt;/code&amp;gt;: The participant whose attributes are being updated. This is passed in to be modified by the function to be used to assign each of the participant's attribute values that are representative of its assigned role.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Behavior===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Use &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;participants_helper&amp;lt;/code&amp;gt; in order to get all necessary permission boolean values for a given participant role&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Assign each of the permission boolean values (&amp;lt;code&amp;gt;can_submit&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_review&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_take_quiz&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_mentor&amp;lt;/code&amp;gt;)&amp;lt;/li&amp;gt; from the helper method to their respective database attribute counterparts in Participant&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Post-Demo Changes==&lt;br /&gt;
&lt;br /&gt;
There were three notable topics that were brought up during the final demo presentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The renaming of &amp;lt;code&amp;gt;get_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;get_participants_by_assignment&amp;lt;/code&amp;gt; to something more suitable to its purpose in rendering the JSON of a list of participants&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Consider the application of &amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; within &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Update the wiki to provide descriptions for each of the methods included in &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt; (See Methods subsection in the Implementation section)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Renaming &amp;lt;code&amp;gt;get_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;get_participants_by_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
These two functions were renamed (once again) to something that better fit the functionality and purpose of the function. Since these functions are meant to render the lists of participants gotten from their respective parameters and use the ID values for each, both of the functions were renamed to &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt; respectively. The renaming of the filter methods was also brought up, but those functions actually do use the objects themselves as parameters, so have been left as is for the time being.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; within &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
We reconsidered the use of these methods within the controller since it was somewhat odd that it would have these methods. However, we concluded that, since the find methods are helper methods that are private and not open to be used by other parts of the code, to be fine to leave as is. This is mostly because they are simple helper methods that get the current user and assignment and return them, rendering an error if they do not exist.&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches all participants associated with the specified user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;user_id [Integer]&amp;lt;/code&amp;gt;: ID of the user&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; A JSON array of participant objects&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized for the action&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If the user does not exist&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If the query fails unexpectedly&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Renamed from &amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def render_participants_by_user_id&lt;br /&gt;
    user = find_user if params[:user_id].present?&lt;br /&gt;
    return if params[:user_id].present? &amp;amp;&amp;amp; user.nil?&lt;br /&gt;
&lt;br /&gt;
    participants = filter_participants_by_user(user)&lt;br /&gt;
&lt;br /&gt;
    if participants.nil?&lt;br /&gt;
      render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participants, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Fetches all participants associated with a specific assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment_id [Integer]&amp;lt;/code&amp;gt;: ID of the assignment&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; A JSON array of participant objects&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized for the action&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If the assignment does not exist&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If the query fails unexpectedly&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Renamed from &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def render_participants_by_assignment_id&lt;br /&gt;
    assignment = find_assignment if params[:assignment_id].present?&lt;br /&gt;
    return if params[:assignment_id].present? &amp;amp;&amp;amp; assignment.nil?&lt;br /&gt;
&lt;br /&gt;
    participants = filter_participants_by_assignment(assignment)&lt;br /&gt;
&lt;br /&gt;
    if participants.nil?&lt;br /&gt;
      render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participants, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;show&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches the details of a specific participant by their ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; JSON representation of the participant&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If the participant does not exist&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If the lookup fails&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Standardized participant lookup to return proper HTTP codes&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def show&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if participant.nil?&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adds a user as a participant to an assignment with the specified authorization (role and permissions).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant[user_id] [Integer]&amp;lt;/code&amp;gt;: ID of the user&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant[assignment_id] [Integer]&amp;lt;/code&amp;gt;: ID of the assignment&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: Role assigned to the participant (reader, reviewer, submitter, mentor)&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;201 Created:&amp;lt;/b&amp;gt; Participant successfully added&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If user or assignment is not found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If authorization is invalid or save fails&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Introduced role-based permission assignment during participant creation&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def add_participant_to_assignment&lt;br /&gt;
    user = find_user&lt;br /&gt;
    return unless user&lt;br /&gt;
&lt;br /&gt;
    assignment = find_assignment&lt;br /&gt;
    return unless assignment&lt;br /&gt;
&lt;br /&gt;
    authorization = validate_authorization&lt;br /&gt;
    return unless authorization&lt;br /&gt;
&lt;br /&gt;
    participant = assignment.add_participant(user)&lt;br /&gt;
    assign_participant_permissions(authorization, participant)&lt;br /&gt;
&lt;br /&gt;
    if participant.save&lt;br /&gt;
      render json: participant, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;update_authorization&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Updates the authorization (role) of an existing participant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: New role to assign (reader, reviewer, submitter, mentor)&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;201 Created:&amp;lt;/b&amp;gt; Authorization updated successfully&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If participant is not found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If authorization is invalid&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Added validation for authorization role values&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = find_participant&lt;br /&gt;
    return unless participant&lt;br /&gt;
&lt;br /&gt;
    authorization = validate_authorization&lt;br /&gt;
    return unless authorization&lt;br /&gt;
&lt;br /&gt;
    assign_participant_permissions(authorization, participant)&lt;br /&gt;
&lt;br /&gt;
    if participant.save&lt;br /&gt;
      render json: participant, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;destroy&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deletes a participant from the system. Optionally includes assignment and team context in the success message.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment_id [Integer] (optional)&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;team_id [Integer] (optional)&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; Success message indicating deletion&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If participant is not found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If deletion fails&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Enhanced success message based on team/assignment presence&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def destroy&lt;br /&gt;
    participant = Participant.find_by(id: params[:id])&lt;br /&gt;
  &lt;br /&gt;
    if participant.nil?&lt;br /&gt;
      render json: { error: 'Not Found' }, status: :not_found&lt;br /&gt;
    elsif participant.destroy&lt;br /&gt;
      successful_deletion_message = if params[:team_id].nil?&lt;br /&gt;
                                      &amp;quot;Participant #{params[:id]} in Assignment #{params[:assignment_id]} has been deleted successfully!&amp;quot;&lt;br /&gt;
                                    else&lt;br /&gt;
                                      &amp;quot;Participant #{params[:id]} in Team #{params[:team_id]} of Assignment #{params[:assignment_id]} has been deleted successfully!&amp;quot;&lt;br /&gt;
                                    end&lt;br /&gt;
      render json: { message: successful_deletion_message }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;participants_params&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Defines the strong parameters allowed when creating or updating a participant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant&amp;lt;/code&amp;gt;: Hash containing fields like user_id, assignment_id, authorization, etc.&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Permitted parameter hash for participant creation/update&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Updated to include all permission and assignment-related fields&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def participant_params&lt;br /&gt;
    params.require(:participant).permit(:user_id, :assignment_id, :authorization, :can_submit,&lt;br /&gt;
                                        :can_review, :can_take_quiz, :can_mentor, :handle,&lt;br /&gt;
                                        :team_id, :join_team_request_id, :permission_granted,&lt;br /&gt;
                                        :topic, :current_stage, :stage_deadline)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches participants associated with a given user, ordered by ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;user [User]&amp;lt;/code&amp;gt;: User object&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Ordered list of participants for the user&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;None&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def filter_participants_by_user(user)&lt;br /&gt;
    participants = Participant.where(user_id: user.id) if user&lt;br /&gt;
    participants.order(:id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches participants associated with a given assignment, ordered by ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment [Assignment]&amp;lt;/code&amp;gt;: Assignment object&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Ordered list of participants for the assignment&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;None&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def filter_participants_by_assignment(assignment)&lt;br /&gt;
    participants = Participant.where(assignment_id: assignment.id) if assignment&lt;br /&gt;
    participants.order(:id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finds a user based on the provided user_id.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;user_id [Integer]&amp;lt;/code&amp;gt;: ID of the user&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;User object if found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;404 error if not found&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Centralized user lookup and error handling&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_user&lt;br /&gt;
    user_id = params[:user_id]&lt;br /&gt;
    user = User.find_by(id: user_id)&lt;br /&gt;
    render json: { error: 'User not found' }, status: :not_found unless user&lt;br /&gt;
    user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finds an assignment based on the provided assignment_id.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment_id [Integer]&amp;lt;/code&amp;gt;: ID of the assignment&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Assignment object if found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;404 error if not found&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Centralized assignment lookup and error handling&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_assignment&lt;br /&gt;
    assignment_id = params[:assignment_id]&lt;br /&gt;
    assignment = Assignment.find_by(id: assignment_id)&lt;br /&gt;
    render json: { error: 'Assignment not found' }, status: :not_found unless assignment&lt;br /&gt;
    assignment&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&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;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finds a participant based on the provided ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Participant object if found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;404 error if not found&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Centralized participant lookup and error handling&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_participant&lt;br /&gt;
    participant_id = params[:id]&lt;br /&gt;
    participant = Participant.find_by(id: participant_id)&lt;br /&gt;
    render json: { error: 'Participant not found' }, status: :not_found unless participant&lt;br /&gt;
    participant&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;assign_participant_permissions&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Assigns permission flags to a participant based on the authorization role provided.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: Role to assign&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant [Participant]&amp;lt;/code&amp;gt;: Participant object&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Participant object with updated permissions&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Added dynamic permission setting based on role&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def assign_participant_permissions(authorization, participant)&lt;br /&gt;
    # Call helper method from participants_helper to retrieve a dictionary containing the&lt;br /&gt;
    # appropriate permission boolean values for the role specified by the authorization string&lt;br /&gt;
    permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
    # Assigns each of the boolean permission values to their respective database counterparts&lt;br /&gt;
    participant.authorization = authorization&lt;br /&gt;
    participant.can_submit = permissions[:can_submit]&lt;br /&gt;
    participant.can_review = permissions[:can_review]&lt;br /&gt;
    participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
    participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;validate_authorization&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Validates that the authorization string is present and one of the accepted roles.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: Authorization role&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Validated authorization string&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;422 error if invalid&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Standardized authorization validation across endpoints&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def validate_authorization&lt;br /&gt;
    valid_authorizations = %w[reader reviewer submitter mentor]&lt;br /&gt;
    authorization = params[:authorization]&lt;br /&gt;
    authorization = authorization.downcase if authorization.present?&lt;br /&gt;
&lt;br /&gt;
    unless authorization&lt;br /&gt;
      render json: { error: 'authorization is required' }, status: :unprocessable_entity&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    unless valid_authorizations.include?(authorization)&lt;br /&gt;
      render json: { error: 'authorization not valid. Valid authorizations are: Reader, Reviewer, Submitter, Mentor' },&lt;br /&gt;
             status: :unprocessable_entity&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    authorization&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Testing Plan=&lt;br /&gt;
&lt;br /&gt;
Of this implementation, also existing 25 tests are passing. We have also given each test their respective IDs within &amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt; as well so that they may be more easily identifiable. For more information about the previous testing plan, please refer to the previous implementation's page here: [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2484._Reimplement_participants_controller.rb]&lt;br /&gt;
&lt;br /&gt;
Below are any modifications to the existing test file (&amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt;) that we have made during the course of this project, alongside the descriptions and rationales behind them:&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
Below are the tests that are included in this implementation. We have updated the test descriptions to include more accurate and detailed information about each of the tests as well. Any tests that have been modified or new will be specified as such:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Retrieve participants by valid user ID (should return participant data)&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Retrieve participants by user ID with no participants (should return empty array)&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Retrieve participants with non-existent user ID (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Retrieve participants by user ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Retrieve participants by valid assignment ID (should return participant data)&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Retrieve participants by non-existent assignment ID (should return 'Assignment not found')&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Retrieve participants by assignment ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Retrieve a participant by valid ID (should return participant details)&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Retrieve a participant by non-existent ID (should return 'Not Found')&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Retrieve a participant by ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Delete a participant by valid ID (should return deletion success message)&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Delete a participant by non-existent ID (should return 'Not Found')&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Delete a participant by ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Update participant authorization with valid data (should return updated authorization)&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Update participant authorization with non-existent participant ID (should return 'Participant not found')&lt;br /&gt;
|-&lt;br /&gt;
| 16 || Update participant authorization with invalid role (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 17 || Update participant authorization with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 18 || Add a participant successfully (should return participant data with authorization)&lt;br /&gt;
|-&lt;br /&gt;
| 19 || Add a participant that already exists (should return duplicate participant error)&lt;br /&gt;
|-&lt;br /&gt;
| 20 || Add a participant with non-existent user ID (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 21 || Add a participant with non-existent assignment ID (should return 'Assignment not found')&lt;br /&gt;
|-&lt;br /&gt;
| 22 || Add a participant with invalid authorization (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 23 || Add a participant with unsupported authorization format (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 24 (NEW) || Add a participant missing user_id in request body (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 25 (NEW) || Add a participant missing assignment_id in request body (should return 'Assignment not found')&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Removed Tests==&lt;br /&gt;
&lt;br /&gt;
These are any tests that we have modified or removed from the previous testing plan. If the test ID is denoted by (Previously), that means that the ID shown was part of the previous implementation's testing plan.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Modification Description &lt;br /&gt;
|-&lt;br /&gt;
| (Previously) 22 || This test was removed as it was redundant. While it is important to check the authorization of the participant that would be invalid, the invalid ID used for this test is a duplicate of the previous test, meaning the result is guaranteed to match that of the previous test regardless of what is meant to be tested.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Next Steps=&lt;br /&gt;
&lt;br /&gt;
Being able to implement this could potentially simplify rendering to the view somewhat in that it could handle simple HTML status code handling. Below are some examples of implementations to serve as a point of reference:&lt;br /&gt;
&lt;br /&gt;
===Example 1===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# Checks if a target object (participant or participants) is not nil and then renders the object.&lt;br /&gt;
# If the object is nil, renders the object errors and sends a not_found_status and if the object&lt;br /&gt;
# exists, renders the object and sends a success status&lt;br /&gt;
# not_found_status default: :unprocessable_entity (422)&lt;br /&gt;
# success_status default: :ok (200)&lt;br /&gt;
def render_object_or_error(object, not_found_status: :unprocessable_entity, success_status: :ok)&lt;br /&gt;
  if object.nil?&lt;br /&gt;
    render json: { error: 'Resource not found' }, status: not_found_status&lt;br /&gt;
  elsif object.respond_to?(:errors) &amp;amp;&amp;amp; object.errors.any?&lt;br /&gt;
    render json: object.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: object, status: success_status&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example is modeled to be specific to the most common use case for this function in the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; by returning the default 422 and 200 error and success codes that are used by three instances of JSON rendering where it checks for whether a list of participants or a single participant is nil. These default values for the status codes are mainly to cover those instances, but could be changed to something else if necessary. The &amp;lt;code&amp;gt;object&amp;lt;/code&amp;gt; parameter is representative of the object that was meant to be rendered given the success or failure of the operation.&lt;br /&gt;
&lt;br /&gt;
===Example 2===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
def render_object_if(conditional, object, error_status, success_status)&lt;br /&gt;
  if conditional&lt;br /&gt;
    render json: { error: 'Resource not found' }, status: error_status&lt;br /&gt;
  else&lt;br /&gt;
    render json: object, status: success_status&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example is a more generic implementation of the function, mandating the error and success status codes rather than providing default values. The point of this was to emphasize readability when glancing over the use of this function. For example, being able to tell that seeing the function being used would immediately tell the reader what the success and failure states were immediately without having to find and inspect the function itself. The &amp;lt;code&amp;gt;conditional&amp;lt;/code&amp;gt; parameter would also allow the function to act similarly to a more readable ternary statement made for rendering.&lt;br /&gt;
&lt;br /&gt;
Implementing this successfully would reduce the amount of repetitive code being used within the controller, as the if-else view rendering is very common in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. We were unable to implement it within our given timeframe, so we opted to divert our focus on other, important tasks that we needed to do.&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Relevant Links =&lt;br /&gt;
&lt;br /&gt;
Pull Request [https://github.com/expertiza/reimplementation-back-end/pull/192] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=165282</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=165282"/>
		<updated>2025-04-27T19:24:20Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Methods (TEMP) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
==Video Overview==&lt;br /&gt;
&lt;br /&gt;
https://youtu.be/4kfz0hrmSg4&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; In the video it shows the test file at the end, but does not mention a last-minute change that numbers all of the tests to make it much easier to keep track of each of the tests and which ones are passing.&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Use of Large Language Models (LLMs)=&lt;br /&gt;
&lt;br /&gt;
For this project, we are using ChatGPT as an LLM helper in determining what issues there are within the code. The use of LLMs in this project will likely be limited to probing for potential issues that exist within the system.&lt;br /&gt;
&lt;br /&gt;
Below we have organized the following prompts and a summary of the output in a table:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 25%&amp;quot; | Prompts !! LLM Output Summary&lt;br /&gt;
|-&lt;br /&gt;
| [Code from &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;]&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt; Are there any ways where we can refactor the code to improve readability, DRYness, and clarity of error handling?&lt;br /&gt;
|| It recognized some of the issues we, as a team, had already identified and suggested fixes that were similar to what we outlined: &amp;lt;b&amp;gt;Redundant JSON Rendering Code&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_Redundant_JSON_Rendering_Code] and &amp;lt;b&amp;gt;Simplifying the Assignment of Participant Fields&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_the_Assignment_of_Participant_Fields]. Additionally, it suggested minor changes that we could implement, such as using &amp;lt;code&amp;gt;Participant.where(...)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; to filter out the code more efficiently instead of getting all database instances every time, as well as the use of strong parameters in &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update_authorization()&amp;lt;/code&amp;gt; to avoid having to implement custom parsing techniques. It also recommends renaming the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; function to something more specific in relation to its purpose (adding a &amp;lt;code&amp;gt;Participant&amp;lt;/code&amp;gt; to an &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Potential Redundant Tests in &amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|| The tests on line 222 and 231 are redundant as only the authorization differs. (Note: This should be investigated to see whether or not this is necessary)&lt;br /&gt;
|-&lt;br /&gt;
| Checking for issues with the current testing files&lt;br /&gt;
|| The &amp;quot;Get Participant by ID call&amp;quot; test was returning a 201 status code instead of the more suitable 200 code&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed information on what prompts we used and the output we got, please visit the page here: [https://docs.google.com/document/d/105_U_Coky-edx7n-tFhD2B5RqmVXxEsKPW_qUaf7bQU/edit?usp=sharing].&lt;br /&gt;
&lt;br /&gt;
=Requirements=&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Some API functions are not returning the correct HTML status messages (e.g. test on line 136 returns 201 instead of 200)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Documentation and comments can be somewhat vague&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;In-line comments should be more descriptive, explaining what the code does in more details&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Tests are not described via comments, but in name alone; some more descriptive comments that explain the tests in more detail would be ideal&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Design / Proposed Solution=&lt;br /&gt;
&lt;br /&gt;
Based on the previous implementation's controller diagram, we have created a new version that contains our proposed changes and modifications to &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[File:Participants_controller_refactor_v1.2.png]]&lt;br /&gt;
&lt;br /&gt;
==Simplifying Redundant JSON Rendering Code==&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Simplifying the Assignment of Participant Fields==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update()&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Provide More Clarity in Function Names==&lt;br /&gt;
&lt;br /&gt;
There are some functions that are somewhat unclear/vague in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. For example, the &amp;lt;code&amp;gt;list_user_participants()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== - Suggested Method Name Improvements ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Old Method Name&lt;br /&gt;
! New Method Name&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Clearer and more descriptive&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Clearer and more descriptive and is consistent with the other get method&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;&lt;br /&gt;
| Describes both creation and authorization setup of participant to assignment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_user_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt;&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_assignment_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Improve Documentation and Comments==&lt;br /&gt;
&lt;br /&gt;
Some of the documentation and in-line comments can be somewhat vague. This can lead to misconceptions about how some functions work or how some of the code can function. Below are potential improvements we plan to make for function descriptions, though these may change with the final implementation.&lt;br /&gt;
&lt;br /&gt;
=== Improved Method Comments ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Original Comment&lt;br /&gt;
! Refactored Comment&lt;br /&gt;
|-&lt;br /&gt;
| render_participants_by_user_id&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
| Retrieves all participants associated with the specified user ID&lt;br /&gt;
|-&lt;br /&gt;
| render_participants_by_assignment_id&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
| Retrieves all participants linked to the specified assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
| Fetch and return the participant with the given ID&lt;br /&gt;
|-&lt;br /&gt;
| add_participant_to_assignment&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
| Creates a new participant for a given assignment and assigns appropriate authorization and permissions&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
| Updates the participant’s authorization role and related permissions&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
| Deletes the participant identified by the given ID and returns a confirmation message&lt;br /&gt;
|-&lt;br /&gt;
| participant_params&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
| Strong parameters: list of attributes allowed for participant creation or update&lt;br /&gt;
|-&lt;br /&gt;
| filter_participants_by_user&lt;br /&gt;
| Filters participants based on the provided user. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by user, if provided&lt;br /&gt;
|-&lt;br /&gt;
| filter_participants_by_assignment&lt;br /&gt;
| Filters participants based on the provided assignment. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by assignment, if provided&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| Validates that the authorization parameter is present and is one of the following valid authorizations: reader, reviewer, submitter, mentor&lt;br /&gt;
| Ensures authorization param is valid and returns it in lowercase; otherwise returns error response&lt;br /&gt;
|-&lt;br /&gt;
| find_user / find_assignment / find_participant&lt;br /&gt;
| Finds a user/assignment/participant by ID and returns it&lt;br /&gt;
| Fetches the corresponding record by ID; renders a not-found error if record does not exist&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Proposed Testing Changes==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add more descriptive comments for tests&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that authorizations are updated correctly&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that inputted path parameters are not missing and valid inputs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Tests at Line 222 and Line 231 are redundant, as the only difference in the test is the authorization, which would not affect what happens if a participant is not found&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
As this is a refactoring project, most of our work on the codebase involved cleaning up the current codebase to better align with foundational code style principles rather than introducing any of kind of new functionality. Our primary focus is to make the code more readable and easier to work with than before. We also took the liberty of fixing some minor errors that we found along the way.&lt;br /&gt;
&lt;br /&gt;
==Changelog==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Naming changes to multiple functions for better clarity and consistency&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Changed HTML status message for &amp;lt;code&amp;gt;show()&amp;lt;/code&amp;gt; from 201 (Created) to 200 (OK) as it is a better fit&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Created the &amp;lt;code&amp;gt;assign_participant_permissions()&amp;lt;/code&amp;gt; method&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Introduced two additional tests and removed a redundant one (see Testing Plan for more details)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Removed redundant queries to &amp;lt;code&amp;gt;Participant.all()&amp;lt;/code&amp;gt; in both filtering methods&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Updated method comments to be more descriptive (see comments table in Design)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Function Name Changes==&lt;br /&gt;
&lt;br /&gt;
The previous implementation had several functions that were strangely named or had names that could be easily misconstrued. The name changes remain the same from the proposal and design section, but for the purpose of clarity, the rationale for each of the functions will be provided below.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
These two functions are meant to render a list of participants given a &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt; respectively. Based on the name alone, it is difficult to tell that the function would render a User/Assignment or Participants. In order to remedy this, we chose the names &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;. The word &amp;quot;list&amp;quot; was replaced by &amp;quot;render&amp;quot; in order to better denote that it is rendering something (json in this case) and the &amp;quot;by&amp;quot; is added to emphasize that the User and Assignment are being used as parameters to search for the Participants. This provides a much clearer picture of what these functions should do compared to before.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; function's name was too vague to be particularly useful in identifying its purpose. To be more accurate, the function was meant to add the user to a given assignment, which would return a participant from the assignment's &amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; function. The new name of the function provides much more context to what it does (&amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_user_participants&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_assignment_participants&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Similar to the list methods that were previously mentioned, it is difficult to tell what exactly these two functions do. While it can be easily seen that it filters something, what is being filtered can be easily mistaken (e.g. does it filter users by participants or participants by users?). The new names, &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt; are much clearer in defining that the User and Assignment are being used as the filter parameters for the function.&lt;br /&gt;
&lt;br /&gt;
==HTML Status Code Change for &amp;lt;code&amp;gt;GET&amp;lt;/code&amp;gt; Call==&lt;br /&gt;
&lt;br /&gt;
The status code being used for this was previously 201, denoting &amp;quot;successful creation&amp;quot;. We have corrected this to a simple 200 code, which signifies an &amp;quot;ok&amp;quot; status message. This issue was actually identified by ChatGPT while we were dowsing for potential issues.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Test modified&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# Tests whether a participant returns properly if provided with a valid Participant ID&lt;br /&gt;
response '200', 'Returns a participant' do&lt;br /&gt;
  let(:id) { participant2.id }&lt;br /&gt;
&lt;br /&gt;
  run_test! do |response|&lt;br /&gt;
    data = JSON.parse(response.body)&lt;br /&gt;
    expect(data['user_id']).to eq(studenta.id)&lt;br /&gt;
    expect(data['assignment_id']).to eq(assignment2.id)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Redundant &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; Queries Removed==&lt;br /&gt;
&lt;br /&gt;
This issue was initially caught by the LLM, ChatGPT, that the team was using in order to find potential issues. We found that simply using &amp;lt;code&amp;gt;Participant.where()&amp;lt;/code&amp;gt; removed the need for the &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; query entirely while changing nothing else about the function, reducing the amount of queries necessary to call the filtering methods, &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# New function&lt;br /&gt;
def filter_participants_by_user(user)&lt;br /&gt;
  participants = Participant.where(user_id: user.id) if user # This would simply get the participants given the proper user ID&lt;br /&gt;
  participants.order(:id)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# Old function&lt;br /&gt;
def filter_participants_by_user(user)&lt;br /&gt;
  participants = Participant.all() # This would obtain the entire list of participants rather than just the necessary ones&lt;br /&gt;
  participants = participants.where(user_id: user.id) if user&lt;br /&gt;
  participants.order(:id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==New Private Method: &amp;lt;code&amp;gt;assign_participant_permissions()&amp;lt;/code&amp;gt;==&lt;br /&gt;
&lt;br /&gt;
The reasoning behind the addition of this method is because of a repeated piece of code that existed in the previous implementation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
participant.authorization = authorization&lt;br /&gt;
participant.can_submit = permissions[:can_submit]&lt;br /&gt;
participant.can_review = permissions[:can_review]&lt;br /&gt;
participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This was repeated in two different contexts: when the Participant was updated or created. This is a violation of the DRY principle, as the same code is repeated multiple times where it could have been reduced to make it more easily readable. In order to resolve this issue, we simply turned this code snippet into a private method that can be called within &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  # An authorization string containing the participant's role is taken and used to determine&lt;br /&gt;
  # what permissions will be allocated to the participant. Each of these permissions will&lt;br /&gt;
  # then be assigned to the Participant's database permission attributes.&lt;br /&gt;
  #&lt;br /&gt;
  # @param [String] authorization: An authorization string that represents the participant's role&lt;br /&gt;
  # @param [Participant] participant: The participant whose authorization permissions are being updated&lt;br /&gt;
  def assign_participant_permissions(authorization, participant)&lt;br /&gt;
    # Call helper method from participants_helper to retrieve a dictionary containing the&lt;br /&gt;
    # appropriate permission boolean values for the role specified by the authorization string&lt;br /&gt;
    permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
    # Assigns each of the boolean permission values to their respective database counterparts&lt;br /&gt;
    participant.authorization = authorization&lt;br /&gt;
    participant.can_submit = permissions[:can_submit]&lt;br /&gt;
    participant.can_review = permissions[:can_review]&lt;br /&gt;
    participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
    participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Description:===&lt;br /&gt;
&lt;br /&gt;
An authorization string containing the participant's role is taken and used to determine what permissions will be allocated to the participant. Each of these permissions will then be assigned to the Participant's database permission attributes.&lt;br /&gt;
&lt;br /&gt;
===Parameters:===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt;: An authorization string that represents the participant's role. This can be either reader, reviewer, submitter, or mentor.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant&amp;lt;/code&amp;gt;: The participant whose attributes are being updated. This is passed in to be modified by the function to be used to assign each of the participant's attribute values that are representative of its assigned role.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Behavior===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Use &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;participants_helper&amp;lt;/code&amp;gt; in order to get all necessary permission boolean values for a given participant role&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Assign each of the permission boolean values (&amp;lt;code&amp;gt;can_submit&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_review&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_take_quiz&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_mentor&amp;lt;/code&amp;gt;)&amp;lt;/li&amp;gt; from the helper method to their respective database attribute counterparts in Participant&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Post-Demo Changes==&lt;br /&gt;
&lt;br /&gt;
There were three notable topics that were brought up during the final demo presentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The renaming of &amp;lt;code&amp;gt;get_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;get_participants_by_assignment&amp;lt;/code&amp;gt; to something more suitable to its purpose in rendering the JSON of a list of participants&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Consider the application of &amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; within &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Update the wiki to provide descriptions for each of the methods included in &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt; (See Methods subsection in the Implementation section)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Renaming &amp;lt;code&amp;gt;get_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;get_participants_by_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
These two functions were renamed (once again) to something that better fit the functionality and purpose of the function. Since these functions are meant to render the lists of participants gotten from their respective parameters and use the ID values for each, both of the functions were renamed to &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt; respectively. The renaming of the filter methods was also brought up, but those functions actually do use the objects themselves as parameters, so have been left as is for the time being.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; within &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
We reconsidered the use of these methods within the controller since it was somewhat odd that it would have these methods. However, we concluded that, since the find methods are helper methods that are private and not open to be used by other parts of the code, to be fine to leave as is. This is mostly because they are simple helper methods that get the current user and assignment and return them, rendering an error if they do not exist.&lt;br /&gt;
&lt;br /&gt;
==Methods (TEMP)==&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches all participants associated with the specified user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;user_id [Integer]&amp;lt;/code&amp;gt;: ID of the user&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; A JSON array of participant objects&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized for the action&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If the user does not exist&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If the query fails unexpectedly&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Renamed from &amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def render_participants_by_user_id&lt;br /&gt;
    user = find_user if params[:user_id].present?&lt;br /&gt;
    return if params[:user_id].present? &amp;amp;&amp;amp; user.nil?&lt;br /&gt;
&lt;br /&gt;
    participants = filter_participants_by_user(user)&lt;br /&gt;
&lt;br /&gt;
    if participants.nil?&lt;br /&gt;
      render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participants, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Fetches all participants associated with a specific assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment_id [Integer]&amp;lt;/code&amp;gt;: ID of the assignment&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; A JSON array of participant objects&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized for the action&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If the assignment does not exist&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If the query fails unexpectedly&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Renamed from &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def render_participants_by_assignment_id&lt;br /&gt;
    assignment = find_assignment if params[:assignment_id].present?&lt;br /&gt;
    return if params[:assignment_id].present? &amp;amp;&amp;amp; assignment.nil?&lt;br /&gt;
&lt;br /&gt;
    participants = filter_participants_by_assignment(assignment)&lt;br /&gt;
&lt;br /&gt;
    if participants.nil?&lt;br /&gt;
      render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participants, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;show&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches the details of a specific participant by their ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;id [Integer]&amp;lt;/code&amp;gt;: ID of the participant&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; JSON representation of the participant&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If the participant does not exist&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If the lookup fails&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Standardized participant lookup to return proper HTTP codes&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def show&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if participant.nil?&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adds a user as a participant to an assignment with the specified authorization (role and permissions).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant[user_id] [Integer]&amp;lt;/code&amp;gt;: ID of the user&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant[assignment_id] [Integer]&amp;lt;/code&amp;gt;: ID of the assignment&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization [String]&amp;lt;/code&amp;gt;: Role assigned to the participant (reader, reviewer, submitter, mentor)&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;201 Created:&amp;lt;/b&amp;gt; Participant successfully added&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If user or assignment is not found&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If authorization is invalid or save fails&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Introduced role-based permission assignment during participant creation&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def add_participant_to_assignment&lt;br /&gt;
    user = find_user&lt;br /&gt;
    return unless user&lt;br /&gt;
&lt;br /&gt;
    assignment = find_assignment&lt;br /&gt;
    return unless assignment&lt;br /&gt;
&lt;br /&gt;
    authorization = validate_authorization&lt;br /&gt;
    return unless authorization&lt;br /&gt;
&lt;br /&gt;
    participant = assignment.add_participant(user)&lt;br /&gt;
    assign_participant_permissions(authorization, participant)&lt;br /&gt;
&lt;br /&gt;
    if participant.save&lt;br /&gt;
      render json: participant, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;update_authorization&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = find_participant&lt;br /&gt;
    return unless participant&lt;br /&gt;
&lt;br /&gt;
    authorization = validate_authorization&lt;br /&gt;
    return unless authorization&lt;br /&gt;
&lt;br /&gt;
    assign_participant_permissions(authorization, participant)&lt;br /&gt;
&lt;br /&gt;
    if participant.save&lt;br /&gt;
      render json: participant, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;destroy&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def destroy&lt;br /&gt;
    participant = Participant.find_by(id: params[:id])&lt;br /&gt;
  &lt;br /&gt;
    if participant.nil?&lt;br /&gt;
      render json: { error: 'Not Found' }, status: :not_found&lt;br /&gt;
    elsif participant.destroy&lt;br /&gt;
      successful_deletion_message = if params[:team_id].nil?&lt;br /&gt;
                                      &amp;quot;Participant #{params[:id]} in Assignment #{params[:assignment_id]} has been deleted successfully!&amp;quot;&lt;br /&gt;
                                    else&lt;br /&gt;
                                      &amp;quot;Participant #{params[:id]} in Team #{params[:team_id]} of Assignment #{params[:assignment_id]} has been deleted successfully!&amp;quot;&lt;br /&gt;
                                    end&lt;br /&gt;
      render json: { message: successful_deletion_message }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;participants_params&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def participant_params&lt;br /&gt;
    params.require(:participant).permit(:user_id, :assignment_id, :authorization, :can_submit,&lt;br /&gt;
                                        :can_review, :can_take_quiz, :can_mentor, :handle,&lt;br /&gt;
                                        :team_id, :join_team_request_id, :permission_granted,&lt;br /&gt;
                                        :topic, :current_stage, :stage_deadline)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def filter_participants_by_user(user)&lt;br /&gt;
    participants = Participant.where(user_id: user.id) if user&lt;br /&gt;
    participants.order(:id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def filter_participants_by_assignment(assignment)&lt;br /&gt;
    participants = Participant.where(assignment_id: assignment.id) if assignment&lt;br /&gt;
    participants.order(:id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_user&lt;br /&gt;
    user_id = params[:user_id]&lt;br /&gt;
    user = User.find_by(id: user_id)&lt;br /&gt;
    render json: { error: 'User not found' }, status: :not_found unless user&lt;br /&gt;
    user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_assignment&lt;br /&gt;
    assignment_id = params[:assignment_id]&lt;br /&gt;
    assignment = Assignment.find_by(id: assignment_id)&lt;br /&gt;
    render json: { error: 'Assignment not found' }, status: :not_found unless assignment&lt;br /&gt;
    assignment&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&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;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_participant&lt;br /&gt;
    participant_id = params[:id]&lt;br /&gt;
    participant = Participant.find_by(id: participant_id)&lt;br /&gt;
    render json: { error: 'Participant not found' }, status: :not_found unless participant&lt;br /&gt;
    participant&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;assign_participant_permissions&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def assign_participant_permissions(authorization, participant)&lt;br /&gt;
    # Call helper method from participants_helper to retrieve a dictionary containing the&lt;br /&gt;
    # appropriate permission boolean values for the role specified by the authorization string&lt;br /&gt;
    permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
    # Assigns each of the boolean permission values to their respective database counterparts&lt;br /&gt;
    participant.authorization = authorization&lt;br /&gt;
    participant.can_submit = permissions[:can_submit]&lt;br /&gt;
    participant.can_review = permissions[:can_review]&lt;br /&gt;
    participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
    participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;validate_authorization&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def validate_authorization&lt;br /&gt;
    valid_authorizations = %w[reader reviewer submitter mentor]&lt;br /&gt;
    authorization = params[:authorization]&lt;br /&gt;
    authorization = authorization.downcase if authorization.present?&lt;br /&gt;
&lt;br /&gt;
    unless authorization&lt;br /&gt;
      render json: { error: 'authorization is required' }, status: :unprocessable_entity&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    unless valid_authorizations.include?(authorization)&lt;br /&gt;
      render json: { error: 'authorization not valid. Valid authorizations are: Reader, Reviewer, Submitter, Mentor' },&lt;br /&gt;
             status: :unprocessable_entity&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    authorization&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Testing Plan=&lt;br /&gt;
&lt;br /&gt;
Of this implementation, also existing 25 tests are passing. We have also given each test their respective IDs within &amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt; as well so that they may be more easily identifiable. For more information about the previous testing plan, please refer to the previous implementation's page here: [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2484._Reimplement_participants_controller.rb]&lt;br /&gt;
&lt;br /&gt;
Below are any modifications to the existing test file (&amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt;) that we have made during the course of this project, alongside the descriptions and rationales behind them:&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
Below are the tests that are included in this implementation. We have updated the test descriptions to include more accurate and detailed information about each of the tests as well. Any tests that have been modified or new will be specified as such:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Retrieve participants by valid user ID (should return participant data)&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Retrieve participants by user ID with no participants (should return empty array)&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Retrieve participants with non-existent user ID (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Retrieve participants by user ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Retrieve participants by valid assignment ID (should return participant data)&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Retrieve participants by non-existent assignment ID (should return 'Assignment not found')&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Retrieve participants by assignment ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Retrieve a participant by valid ID (should return participant details)&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Retrieve a participant by non-existent ID (should return 'Not Found')&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Retrieve a participant by ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Delete a participant by valid ID (should return deletion success message)&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Delete a participant by non-existent ID (should return 'Not Found')&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Delete a participant by ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Update participant authorization with valid data (should return updated authorization)&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Update participant authorization with non-existent participant ID (should return 'Participant not found')&lt;br /&gt;
|-&lt;br /&gt;
| 16 || Update participant authorization with invalid role (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 17 || Update participant authorization with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 18 || Add a participant successfully (should return participant data with authorization)&lt;br /&gt;
|-&lt;br /&gt;
| 19 || Add a participant that already exists (should return duplicate participant error)&lt;br /&gt;
|-&lt;br /&gt;
| 20 || Add a participant with non-existent user ID (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 21 || Add a participant with non-existent assignment ID (should return 'Assignment not found')&lt;br /&gt;
|-&lt;br /&gt;
| 22 || Add a participant with invalid authorization (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 23 || Add a participant with unsupported authorization format (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 24 (NEW) || Add a participant missing user_id in request body (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 25 (NEW) || Add a participant missing assignment_id in request body (should return 'Assignment not found')&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Removed Tests==&lt;br /&gt;
&lt;br /&gt;
These are any tests that we have modified or removed from the previous testing plan. If the test ID is denoted by (Previously), that means that the ID shown was part of the previous implementation's testing plan.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Modification Description &lt;br /&gt;
|-&lt;br /&gt;
| (Previously) 22 || This test was removed as it was redundant. While it is important to check the authorization of the participant that would be invalid, the invalid ID used for this test is a duplicate of the previous test, meaning the result is guaranteed to match that of the previous test regardless of what is meant to be tested.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Next Steps=&lt;br /&gt;
&lt;br /&gt;
Being able to implement this could potentially simplify rendering to the view somewhat in that it could handle simple HTML status code handling. Below are some examples of implementations to serve as a point of reference:&lt;br /&gt;
&lt;br /&gt;
===Example 1===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# Checks if a target object (participant or participants) is not nil and then renders the object.&lt;br /&gt;
# If the object is nil, renders the object errors and sends a not_found_status and if the object&lt;br /&gt;
# exists, renders the object and sends a success status&lt;br /&gt;
# not_found_status default: :unprocessable_entity (422)&lt;br /&gt;
# success_status default: :ok (200)&lt;br /&gt;
def render_object_or_error(object, not_found_status: :unprocessable_entity, success_status: :ok)&lt;br /&gt;
  if object.nil?&lt;br /&gt;
    render json: { error: 'Resource not found' }, status: not_found_status&lt;br /&gt;
  elsif object.respond_to?(:errors) &amp;amp;&amp;amp; object.errors.any?&lt;br /&gt;
    render json: object.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: object, status: success_status&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example is modeled to be specific to the most common use case for this function in the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; by returning the default 422 and 200 error and success codes that are used by three instances of JSON rendering where it checks for whether a list of participants or a single participant is nil. These default values for the status codes are mainly to cover those instances, but could be changed to something else if necessary. The &amp;lt;code&amp;gt;object&amp;lt;/code&amp;gt; parameter is representative of the object that was meant to be rendered given the success or failure of the operation.&lt;br /&gt;
&lt;br /&gt;
===Example 2===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
def render_object_if(conditional, object, error_status, success_status)&lt;br /&gt;
  if conditional&lt;br /&gt;
    render json: { error: 'Resource not found' }, status: error_status&lt;br /&gt;
  else&lt;br /&gt;
    render json: object, status: success_status&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example is a more generic implementation of the function, mandating the error and success status codes rather than providing default values. The point of this was to emphasize readability when glancing over the use of this function. For example, being able to tell that seeing the function being used would immediately tell the reader what the success and failure states were immediately without having to find and inspect the function itself. The &amp;lt;code&amp;gt;conditional&amp;lt;/code&amp;gt; parameter would also allow the function to act similarly to a more readable ternary statement made for rendering.&lt;br /&gt;
&lt;br /&gt;
Implementing this successfully would reduce the amount of repetitive code being used within the controller, as the if-else view rendering is very common in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. We were unable to implement it within our given timeframe, so we opted to divert our focus on other, important tasks that we needed to do.&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Relevant Links =&lt;br /&gt;
&lt;br /&gt;
Pull Request [https://github.com/expertiza/reimplementation-back-end/pull/192] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=165281</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=165281"/>
		<updated>2025-04-27T19:21:43Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Methods (TEMP) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
==Video Overview==&lt;br /&gt;
&lt;br /&gt;
https://youtu.be/4kfz0hrmSg4&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; In the video it shows the test file at the end, but does not mention a last-minute change that numbers all of the tests to make it much easier to keep track of each of the tests and which ones are passing.&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Use of Large Language Models (LLMs)=&lt;br /&gt;
&lt;br /&gt;
For this project, we are using ChatGPT as an LLM helper in determining what issues there are within the code. The use of LLMs in this project will likely be limited to probing for potential issues that exist within the system.&lt;br /&gt;
&lt;br /&gt;
Below we have organized the following prompts and a summary of the output in a table:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 25%&amp;quot; | Prompts !! LLM Output Summary&lt;br /&gt;
|-&lt;br /&gt;
| [Code from &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;]&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt; Are there any ways where we can refactor the code to improve readability, DRYness, and clarity of error handling?&lt;br /&gt;
|| It recognized some of the issues we, as a team, had already identified and suggested fixes that were similar to what we outlined: &amp;lt;b&amp;gt;Redundant JSON Rendering Code&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_Redundant_JSON_Rendering_Code] and &amp;lt;b&amp;gt;Simplifying the Assignment of Participant Fields&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_the_Assignment_of_Participant_Fields]. Additionally, it suggested minor changes that we could implement, such as using &amp;lt;code&amp;gt;Participant.where(...)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; to filter out the code more efficiently instead of getting all database instances every time, as well as the use of strong parameters in &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update_authorization()&amp;lt;/code&amp;gt; to avoid having to implement custom parsing techniques. It also recommends renaming the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; function to something more specific in relation to its purpose (adding a &amp;lt;code&amp;gt;Participant&amp;lt;/code&amp;gt; to an &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Potential Redundant Tests in &amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|| The tests on line 222 and 231 are redundant as only the authorization differs. (Note: This should be investigated to see whether or not this is necessary)&lt;br /&gt;
|-&lt;br /&gt;
| Checking for issues with the current testing files&lt;br /&gt;
|| The &amp;quot;Get Participant by ID call&amp;quot; test was returning a 201 status code instead of the more suitable 200 code&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed information on what prompts we used and the output we got, please visit the page here: [https://docs.google.com/document/d/105_U_Coky-edx7n-tFhD2B5RqmVXxEsKPW_qUaf7bQU/edit?usp=sharing].&lt;br /&gt;
&lt;br /&gt;
=Requirements=&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Some API functions are not returning the correct HTML status messages (e.g. test on line 136 returns 201 instead of 200)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Documentation and comments can be somewhat vague&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;In-line comments should be more descriptive, explaining what the code does in more details&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Tests are not described via comments, but in name alone; some more descriptive comments that explain the tests in more detail would be ideal&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Design / Proposed Solution=&lt;br /&gt;
&lt;br /&gt;
Based on the previous implementation's controller diagram, we have created a new version that contains our proposed changes and modifications to &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[File:Participants_controller_refactor_v1.2.png]]&lt;br /&gt;
&lt;br /&gt;
==Simplifying Redundant JSON Rendering Code==&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Simplifying the Assignment of Participant Fields==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update()&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Provide More Clarity in Function Names==&lt;br /&gt;
&lt;br /&gt;
There are some functions that are somewhat unclear/vague in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. For example, the &amp;lt;code&amp;gt;list_user_participants()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== - Suggested Method Name Improvements ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Old Method Name&lt;br /&gt;
! New Method Name&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Clearer and more descriptive&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Clearer and more descriptive and is consistent with the other get method&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;&lt;br /&gt;
| Describes both creation and authorization setup of participant to assignment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_user_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt;&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_assignment_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Improve Documentation and Comments==&lt;br /&gt;
&lt;br /&gt;
Some of the documentation and in-line comments can be somewhat vague. This can lead to misconceptions about how some functions work or how some of the code can function. Below are potential improvements we plan to make for function descriptions, though these may change with the final implementation.&lt;br /&gt;
&lt;br /&gt;
=== Improved Method Comments ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Original Comment&lt;br /&gt;
! Refactored Comment&lt;br /&gt;
|-&lt;br /&gt;
| render_participants_by_user_id&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
| Retrieves all participants associated with the specified user ID&lt;br /&gt;
|-&lt;br /&gt;
| render_participants_by_assignment_id&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
| Retrieves all participants linked to the specified assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
| Fetch and return the participant with the given ID&lt;br /&gt;
|-&lt;br /&gt;
| add_participant_to_assignment&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
| Creates a new participant for a given assignment and assigns appropriate authorization and permissions&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
| Updates the participant’s authorization role and related permissions&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
| Deletes the participant identified by the given ID and returns a confirmation message&lt;br /&gt;
|-&lt;br /&gt;
| participant_params&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
| Strong parameters: list of attributes allowed for participant creation or update&lt;br /&gt;
|-&lt;br /&gt;
| filter_participants_by_user&lt;br /&gt;
| Filters participants based on the provided user. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by user, if provided&lt;br /&gt;
|-&lt;br /&gt;
| filter_participants_by_assignment&lt;br /&gt;
| Filters participants based on the provided assignment. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by assignment, if provided&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| Validates that the authorization parameter is present and is one of the following valid authorizations: reader, reviewer, submitter, mentor&lt;br /&gt;
| Ensures authorization param is valid and returns it in lowercase; otherwise returns error response&lt;br /&gt;
|-&lt;br /&gt;
| find_user / find_assignment / find_participant&lt;br /&gt;
| Finds a user/assignment/participant by ID and returns it&lt;br /&gt;
| Fetches the corresponding record by ID; renders a not-found error if record does not exist&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Proposed Testing Changes==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add more descriptive comments for tests&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that authorizations are updated correctly&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that inputted path parameters are not missing and valid inputs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Tests at Line 222 and Line 231 are redundant, as the only difference in the test is the authorization, which would not affect what happens if a participant is not found&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
As this is a refactoring project, most of our work on the codebase involved cleaning up the current codebase to better align with foundational code style principles rather than introducing any of kind of new functionality. Our primary focus is to make the code more readable and easier to work with than before. We also took the liberty of fixing some minor errors that we found along the way.&lt;br /&gt;
&lt;br /&gt;
==Changelog==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Naming changes to multiple functions for better clarity and consistency&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Changed HTML status message for &amp;lt;code&amp;gt;show()&amp;lt;/code&amp;gt; from 201 (Created) to 200 (OK) as it is a better fit&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Created the &amp;lt;code&amp;gt;assign_participant_permissions()&amp;lt;/code&amp;gt; method&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Introduced two additional tests and removed a redundant one (see Testing Plan for more details)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Removed redundant queries to &amp;lt;code&amp;gt;Participant.all()&amp;lt;/code&amp;gt; in both filtering methods&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Updated method comments to be more descriptive (see comments table in Design)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Function Name Changes==&lt;br /&gt;
&lt;br /&gt;
The previous implementation had several functions that were strangely named or had names that could be easily misconstrued. The name changes remain the same from the proposal and design section, but for the purpose of clarity, the rationale for each of the functions will be provided below.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
These two functions are meant to render a list of participants given a &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt; respectively. Based on the name alone, it is difficult to tell that the function would render a User/Assignment or Participants. In order to remedy this, we chose the names &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;. The word &amp;quot;list&amp;quot; was replaced by &amp;quot;render&amp;quot; in order to better denote that it is rendering something (json in this case) and the &amp;quot;by&amp;quot; is added to emphasize that the User and Assignment are being used as parameters to search for the Participants. This provides a much clearer picture of what these functions should do compared to before.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; function's name was too vague to be particularly useful in identifying its purpose. To be more accurate, the function was meant to add the user to a given assignment, which would return a participant from the assignment's &amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; function. The new name of the function provides much more context to what it does (&amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_user_participants&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_assignment_participants&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Similar to the list methods that were previously mentioned, it is difficult to tell what exactly these two functions do. While it can be easily seen that it filters something, what is being filtered can be easily mistaken (e.g. does it filter users by participants or participants by users?). The new names, &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt; are much clearer in defining that the User and Assignment are being used as the filter parameters for the function.&lt;br /&gt;
&lt;br /&gt;
==HTML Status Code Change for &amp;lt;code&amp;gt;GET&amp;lt;/code&amp;gt; Call==&lt;br /&gt;
&lt;br /&gt;
The status code being used for this was previously 201, denoting &amp;quot;successful creation&amp;quot;. We have corrected this to a simple 200 code, which signifies an &amp;quot;ok&amp;quot; status message. This issue was actually identified by ChatGPT while we were dowsing for potential issues.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Test modified&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# Tests whether a participant returns properly if provided with a valid Participant ID&lt;br /&gt;
response '200', 'Returns a participant' do&lt;br /&gt;
  let(:id) { participant2.id }&lt;br /&gt;
&lt;br /&gt;
  run_test! do |response|&lt;br /&gt;
    data = JSON.parse(response.body)&lt;br /&gt;
    expect(data['user_id']).to eq(studenta.id)&lt;br /&gt;
    expect(data['assignment_id']).to eq(assignment2.id)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Redundant &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; Queries Removed==&lt;br /&gt;
&lt;br /&gt;
This issue was initially caught by the LLM, ChatGPT, that the team was using in order to find potential issues. We found that simply using &amp;lt;code&amp;gt;Participant.where()&amp;lt;/code&amp;gt; removed the need for the &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; query entirely while changing nothing else about the function, reducing the amount of queries necessary to call the filtering methods, &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# New function&lt;br /&gt;
def filter_participants_by_user(user)&lt;br /&gt;
  participants = Participant.where(user_id: user.id) if user # This would simply get the participants given the proper user ID&lt;br /&gt;
  participants.order(:id)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# Old function&lt;br /&gt;
def filter_participants_by_user(user)&lt;br /&gt;
  participants = Participant.all() # This would obtain the entire list of participants rather than just the necessary ones&lt;br /&gt;
  participants = participants.where(user_id: user.id) if user&lt;br /&gt;
  participants.order(:id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==New Private Method: &amp;lt;code&amp;gt;assign_participant_permissions()&amp;lt;/code&amp;gt;==&lt;br /&gt;
&lt;br /&gt;
The reasoning behind the addition of this method is because of a repeated piece of code that existed in the previous implementation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
participant.authorization = authorization&lt;br /&gt;
participant.can_submit = permissions[:can_submit]&lt;br /&gt;
participant.can_review = permissions[:can_review]&lt;br /&gt;
participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This was repeated in two different contexts: when the Participant was updated or created. This is a violation of the DRY principle, as the same code is repeated multiple times where it could have been reduced to make it more easily readable. In order to resolve this issue, we simply turned this code snippet into a private method that can be called within &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  # An authorization string containing the participant's role is taken and used to determine&lt;br /&gt;
  # what permissions will be allocated to the participant. Each of these permissions will&lt;br /&gt;
  # then be assigned to the Participant's database permission attributes.&lt;br /&gt;
  #&lt;br /&gt;
  # @param [String] authorization: An authorization string that represents the participant's role&lt;br /&gt;
  # @param [Participant] participant: The participant whose authorization permissions are being updated&lt;br /&gt;
  def assign_participant_permissions(authorization, participant)&lt;br /&gt;
    # Call helper method from participants_helper to retrieve a dictionary containing the&lt;br /&gt;
    # appropriate permission boolean values for the role specified by the authorization string&lt;br /&gt;
    permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
    # Assigns each of the boolean permission values to their respective database counterparts&lt;br /&gt;
    participant.authorization = authorization&lt;br /&gt;
    participant.can_submit = permissions[:can_submit]&lt;br /&gt;
    participant.can_review = permissions[:can_review]&lt;br /&gt;
    participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
    participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Description:===&lt;br /&gt;
&lt;br /&gt;
An authorization string containing the participant's role is taken and used to determine what permissions will be allocated to the participant. Each of these permissions will then be assigned to the Participant's database permission attributes.&lt;br /&gt;
&lt;br /&gt;
===Parameters:===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt;: An authorization string that represents the participant's role. This can be either reader, reviewer, submitter, or mentor.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant&amp;lt;/code&amp;gt;: The participant whose attributes are being updated. This is passed in to be modified by the function to be used to assign each of the participant's attribute values that are representative of its assigned role.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Behavior===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Use &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;participants_helper&amp;lt;/code&amp;gt; in order to get all necessary permission boolean values for a given participant role&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Assign each of the permission boolean values (&amp;lt;code&amp;gt;can_submit&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_review&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_take_quiz&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_mentor&amp;lt;/code&amp;gt;)&amp;lt;/li&amp;gt; from the helper method to their respective database attribute counterparts in Participant&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Post-Demo Changes==&lt;br /&gt;
&lt;br /&gt;
There were three notable topics that were brought up during the final demo presentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The renaming of &amp;lt;code&amp;gt;get_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;get_participants_by_assignment&amp;lt;/code&amp;gt; to something more suitable to its purpose in rendering the JSON of a list of participants&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Consider the application of &amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; within &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Update the wiki to provide descriptions for each of the methods included in &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt; (See Methods subsection in the Implementation section)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Renaming &amp;lt;code&amp;gt;get_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;get_participants_by_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
These two functions were renamed (once again) to something that better fit the functionality and purpose of the function. Since these functions are meant to render the lists of participants gotten from their respective parameters and use the ID values for each, both of the functions were renamed to &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt; respectively. The renaming of the filter methods was also brought up, but those functions actually do use the objects themselves as parameters, so have been left as is for the time being.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; within &amp;lt;code&amp;gt;participants_controller&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
We reconsidered the use of these methods within the controller since it was somewhat odd that it would have these methods. However, we concluded that, since the find methods are helper methods that are private and not open to be used by other parts of the code, to be fine to leave as is. This is mostly because they are simple helper methods that get the current user and assignment and return them, rendering an error if they do not exist.&lt;br /&gt;
&lt;br /&gt;
==Methods (TEMP)==&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetches all participants associated with the specified user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;user_id [Integer]&amp;lt;/code&amp;gt;: ID of the user&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; A JSON array of participant objects&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized for the action&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If the user does not exist&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If the query fails unexpectedly&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Renamed from &amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;render_participants_by_user_id&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def render_participants_by_user_id&lt;br /&gt;
    user = find_user if params[:user_id].present?&lt;br /&gt;
    return if params[:user_id].present? &amp;amp;&amp;amp; user.nil?&lt;br /&gt;
&lt;br /&gt;
    participants = filter_participants_by_user(user)&lt;br /&gt;
&lt;br /&gt;
    if participants.nil?&lt;br /&gt;
      render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participants, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Fetches all participants associated with a specific assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;assignment_id [Integer]&amp;lt;/code&amp;gt;: ID of the assignment&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;200 OK:&amp;lt;/b&amp;gt; A JSON array of participant objects&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;401 Unauthorized:&amp;lt;/b&amp;gt; If the user is not authorized for the action&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;404 Not Found:&amp;lt;/b&amp;gt; If the assignment does not exist&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;422 Unprocessable Entity:&amp;lt;/b&amp;gt; If the query fails unexpectedly&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt; &amp;lt;li&amp;gt;Renamed from &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;render_participants_by_assignment_id&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def render_participants_by_assignment_id&lt;br /&gt;
    assignment = find_assignment if params[:assignment_id].present?&lt;br /&gt;
    return if params[:assignment_id].present? &amp;amp;&amp;amp; assignment.nil?&lt;br /&gt;
&lt;br /&gt;
    participants = filter_participants_by_assignment(assignment)&lt;br /&gt;
&lt;br /&gt;
    if participants.nil?&lt;br /&gt;
      render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participants, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;show&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def show&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if participant.nil?&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def add_participant_to_assignment&lt;br /&gt;
    user = find_user&lt;br /&gt;
    return unless user&lt;br /&gt;
&lt;br /&gt;
    assignment = find_assignment&lt;br /&gt;
    return unless assignment&lt;br /&gt;
&lt;br /&gt;
    authorization = validate_authorization&lt;br /&gt;
    return unless authorization&lt;br /&gt;
&lt;br /&gt;
    participant = assignment.add_participant(user)&lt;br /&gt;
    assign_participant_permissions(authorization, participant)&lt;br /&gt;
&lt;br /&gt;
    if participant.save&lt;br /&gt;
      render json: participant, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;update_authorization&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = find_participant&lt;br /&gt;
    return unless participant&lt;br /&gt;
&lt;br /&gt;
    authorization = validate_authorization&lt;br /&gt;
    return unless authorization&lt;br /&gt;
&lt;br /&gt;
    assign_participant_permissions(authorization, participant)&lt;br /&gt;
&lt;br /&gt;
    if participant.save&lt;br /&gt;
      render json: participant, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;destroy&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def destroy&lt;br /&gt;
    participant = Participant.find_by(id: params[:id])&lt;br /&gt;
  &lt;br /&gt;
    if participant.nil?&lt;br /&gt;
      render json: { error: 'Not Found' }, status: :not_found&lt;br /&gt;
    elsif participant.destroy&lt;br /&gt;
      successful_deletion_message = if params[:team_id].nil?&lt;br /&gt;
                                      &amp;quot;Participant #{params[:id]} in Assignment #{params[:assignment_id]} has been deleted successfully!&amp;quot;&lt;br /&gt;
                                    else&lt;br /&gt;
                                      &amp;quot;Participant #{params[:id]} in Team #{params[:team_id]} of Assignment #{params[:assignment_id]} has been deleted successfully!&amp;quot;&lt;br /&gt;
                                    end&lt;br /&gt;
      render json: { message: successful_deletion_message }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;participants_params&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def participant_params&lt;br /&gt;
    params.require(:participant).permit(:user_id, :assignment_id, :authorization, :can_submit,&lt;br /&gt;
                                        :can_review, :can_take_quiz, :can_mentor, :handle,&lt;br /&gt;
                                        :team_id, :join_team_request_id, :permission_granted,&lt;br /&gt;
                                        :topic, :current_stage, :stage_deadline)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def filter_participants_by_user(user)&lt;br /&gt;
    participants = Participant.where(user_id: user.id) if user&lt;br /&gt;
    participants.order(:id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def filter_participants_by_assignment(assignment)&lt;br /&gt;
    participants = Participant.where(assignment_id: assignment.id) if assignment&lt;br /&gt;
    participants.order(:id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_user&lt;br /&gt;
    user_id = params[:user_id]&lt;br /&gt;
    user = User.find_by(id: user_id)&lt;br /&gt;
    render json: { error: 'User not found' }, status: :not_found unless user&lt;br /&gt;
    user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_assignment&lt;br /&gt;
    assignment_id = params[:assignment_id]&lt;br /&gt;
    assignment = Assignment.find_by(id: assignment_id)&lt;br /&gt;
    render json: { error: 'Assignment not found' }, status: :not_found unless assignment&lt;br /&gt;
    assignment&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&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;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def find_participant&lt;br /&gt;
    participant_id = params[:id]&lt;br /&gt;
    participant = Participant.find_by(id: participant_id)&lt;br /&gt;
    render json: { error: 'Participant not found' }, status: :not_found unless participant&lt;br /&gt;
    participant&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;assign_participant_permissions&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def assign_participant_permissions(authorization, participant)&lt;br /&gt;
    # Call helper method from participants_helper to retrieve a dictionary containing the&lt;br /&gt;
    # appropriate permission boolean values for the role specified by the authorization string&lt;br /&gt;
    permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
    # Assigns each of the boolean permission values to their respective database counterparts&lt;br /&gt;
    participant.authorization = authorization&lt;br /&gt;
    participant.can_submit = permissions[:can_submit]&lt;br /&gt;
    participant.can_review = permissions[:can_review]&lt;br /&gt;
    participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
    participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;validate_authorization&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Returns&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Notable Changes&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  def validate_authorization&lt;br /&gt;
    valid_authorizations = %w[reader reviewer submitter mentor]&lt;br /&gt;
    authorization = params[:authorization]&lt;br /&gt;
    authorization = authorization.downcase if authorization.present?&lt;br /&gt;
&lt;br /&gt;
    unless authorization&lt;br /&gt;
      render json: { error: 'authorization is required' }, status: :unprocessable_entity&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    unless valid_authorizations.include?(authorization)&lt;br /&gt;
      render json: { error: 'authorization not valid. Valid authorizations are: Reader, Reviewer, Submitter, Mentor' },&lt;br /&gt;
             status: :unprocessable_entity&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    authorization&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Testing Plan=&lt;br /&gt;
&lt;br /&gt;
Of this implementation, also existing 25 tests are passing. We have also given each test their respective IDs within &amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt; as well so that they may be more easily identifiable. For more information about the previous testing plan, please refer to the previous implementation's page here: [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2484._Reimplement_participants_controller.rb]&lt;br /&gt;
&lt;br /&gt;
Below are any modifications to the existing test file (&amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt;) that we have made during the course of this project, alongside the descriptions and rationales behind them:&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
Below are the tests that are included in this implementation. We have updated the test descriptions to include more accurate and detailed information about each of the tests as well. Any tests that have been modified or new will be specified as such:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Retrieve participants by valid user ID (should return participant data)&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Retrieve participants by user ID with no participants (should return empty array)&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Retrieve participants with non-existent user ID (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Retrieve participants by user ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Retrieve participants by valid assignment ID (should return participant data)&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Retrieve participants by non-existent assignment ID (should return 'Assignment not found')&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Retrieve participants by assignment ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Retrieve a participant by valid ID (should return participant details)&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Retrieve a participant by non-existent ID (should return 'Not Found')&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Retrieve a participant by ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Delete a participant by valid ID (should return deletion success message)&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Delete a participant by non-existent ID (should return 'Not Found')&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Delete a participant by ID with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Update participant authorization with valid data (should return updated authorization)&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Update participant authorization with non-existent participant ID (should return 'Participant not found')&lt;br /&gt;
|-&lt;br /&gt;
| 16 || Update participant authorization with invalid role (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 17 || Update participant authorization with invalid token (should return 'Not Authorized')&lt;br /&gt;
|-&lt;br /&gt;
| 18 || Add a participant successfully (should return participant data with authorization)&lt;br /&gt;
|-&lt;br /&gt;
| 19 || Add a participant that already exists (should return duplicate participant error)&lt;br /&gt;
|-&lt;br /&gt;
| 20 || Add a participant with non-existent user ID (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 21 || Add a participant with non-existent assignment ID (should return 'Assignment not found')&lt;br /&gt;
|-&lt;br /&gt;
| 22 || Add a participant with invalid authorization (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 23 || Add a participant with unsupported authorization format (should return 'authorization not valid')&lt;br /&gt;
|-&lt;br /&gt;
| 24 (NEW) || Add a participant missing user_id in request body (should return 'User not found')&lt;br /&gt;
|-&lt;br /&gt;
| 25 (NEW) || Add a participant missing assignment_id in request body (should return 'Assignment not found')&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Removed Tests==&lt;br /&gt;
&lt;br /&gt;
These are any tests that we have modified or removed from the previous testing plan. If the test ID is denoted by (Previously), that means that the ID shown was part of the previous implementation's testing plan.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Modification Description &lt;br /&gt;
|-&lt;br /&gt;
| (Previously) 22 || This test was removed as it was redundant. While it is important to check the authorization of the participant that would be invalid, the invalid ID used for this test is a duplicate of the previous test, meaning the result is guaranteed to match that of the previous test regardless of what is meant to be tested.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Next Steps=&lt;br /&gt;
&lt;br /&gt;
Being able to implement this could potentially simplify rendering to the view somewhat in that it could handle simple HTML status code handling. Below are some examples of implementations to serve as a point of reference:&lt;br /&gt;
&lt;br /&gt;
===Example 1===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# Checks if a target object (participant or participants) is not nil and then renders the object.&lt;br /&gt;
# If the object is nil, renders the object errors and sends a not_found_status and if the object&lt;br /&gt;
# exists, renders the object and sends a success status&lt;br /&gt;
# not_found_status default: :unprocessable_entity (422)&lt;br /&gt;
# success_status default: :ok (200)&lt;br /&gt;
def render_object_or_error(object, not_found_status: :unprocessable_entity, success_status: :ok)&lt;br /&gt;
  if object.nil?&lt;br /&gt;
    render json: { error: 'Resource not found' }, status: not_found_status&lt;br /&gt;
  elsif object.respond_to?(:errors) &amp;amp;&amp;amp; object.errors.any?&lt;br /&gt;
    render json: object.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: object, status: success_status&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example is modeled to be specific to the most common use case for this function in the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; by returning the default 422 and 200 error and success codes that are used by three instances of JSON rendering where it checks for whether a list of participants or a single participant is nil. These default values for the status codes are mainly to cover those instances, but could be changed to something else if necessary. The &amp;lt;code&amp;gt;object&amp;lt;/code&amp;gt; parameter is representative of the object that was meant to be rendered given the success or failure of the operation.&lt;br /&gt;
&lt;br /&gt;
===Example 2===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
def render_object_if(conditional, object, error_status, success_status)&lt;br /&gt;
  if conditional&lt;br /&gt;
    render json: { error: 'Resource not found' }, status: error_status&lt;br /&gt;
  else&lt;br /&gt;
    render json: object, status: success_status&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example is a more generic implementation of the function, mandating the error and success status codes rather than providing default values. The point of this was to emphasize readability when glancing over the use of this function. For example, being able to tell that seeing the function being used would immediately tell the reader what the success and failure states were immediately without having to find and inspect the function itself. The &amp;lt;code&amp;gt;conditional&amp;lt;/code&amp;gt; parameter would also allow the function to act similarly to a more readable ternary statement made for rendering.&lt;br /&gt;
&lt;br /&gt;
Implementing this successfully would reduce the amount of repetitive code being used within the controller, as the if-else view rendering is very common in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. We were unable to implement it within our given timeframe, so we opted to divert our focus on other, important tasks that we needed to do.&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Relevant Links =&lt;br /&gt;
&lt;br /&gt;
Pull Request [https://github.com/expertiza/reimplementation-back-end/pull/192] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=164615</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=164615"/>
		<updated>2025-04-22T16:18:48Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Issues and Next Steps */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
=Use of Large Language Models (LLMs)=&lt;br /&gt;
&lt;br /&gt;
For this project, we are using ChatGPT as an LLM helper in determining what issues there are within the code. The use of LLMs in this project will likely be limited to probing for potential issues that exist within the system.&lt;br /&gt;
&lt;br /&gt;
Below we have organized the following prompts and a summary of the output in a table:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 25%&amp;quot; | Prompts !! LLM Output Summary&lt;br /&gt;
|-&lt;br /&gt;
| [Code from &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;]&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt; Are there any ways where we can refactor the code to improve readability, DRYness, and clarity of error handling?&lt;br /&gt;
|| It recognized some of the issues we, as a team, had already identified and suggested fixes that were similar to what we outlined: &amp;lt;b&amp;gt;Redundant JSON Rendering Code&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_Redundant_JSON_Rendering_Code] and &amp;lt;b&amp;gt;Simplifying the Assignment of Participant Fields&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_the_Assignment_of_Participant_Fields]. Additionally, it suggested minor changes that we could implement, such as using &amp;lt;code&amp;gt;Participant.where(...)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; to filter out the code more efficiently instead of getting all database instances every time, as well as the use of strong parameters in &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update_authorization()&amp;lt;/code&amp;gt; to avoid having to implement custom parsing techniques. It also recommends renaming the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; function to something more specific in relation to its purpose (adding a &amp;lt;code&amp;gt;Participant&amp;lt;/code&amp;gt; to an &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Potential Redundant Tests in &amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|| The tests on line 222 and 231 are redundant as only the authorization differs. (Note: This should be investigated to see whether or not this is necessary)&lt;br /&gt;
|-&lt;br /&gt;
| Checking for issues with the current testing files&lt;br /&gt;
|| The &amp;quot;Get Participant by ID call&amp;quot; test was returning a 201 status code instead of the more suitable 200 code&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed information on what prompts we used and the output we got, please visit the page here: [https://docs.google.com/document/d/105_U_Coky-edx7n-tFhD2B5RqmVXxEsKPW_qUaf7bQU/edit?usp=sharing].&lt;br /&gt;
&lt;br /&gt;
=Requirements=&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Some API functions are not returning the correct HTML status messages (e.g. test on line 136 returns 201 instead of 200)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Documentation and comments can be somewhat vague&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;In-line comments should be more descriptive, explaining what the code does in more details&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Tests are not described via comments, but in name alone; some more descriptive comments that explain the tests in more detail would be ideal&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Design / Proposed Solution=&lt;br /&gt;
&lt;br /&gt;
Based on the previous implementation's controller diagram, we have created a new version that contains our proposed changes and modifications to &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[File:Participants_controller_refactor.drawio_v1.0.png]]&lt;br /&gt;
&lt;br /&gt;
==Simplifying Redundant JSON Rendering Code==&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Simplifying the Assignment of Participant Fields==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update()&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Provide More Clarity in Function Names==&lt;br /&gt;
&lt;br /&gt;
There are some functions that are somewhat unclear/vague in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. For example, the &amp;lt;code&amp;gt;list_user_participants()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== - Suggested Method Name Improvements ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Old Method Name&lt;br /&gt;
! New Method Name&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;get_participants_by_user&amp;lt;/code&amp;gt;&lt;br /&gt;
| Clearer and more descriptive&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;get_participants_by_assignment&amp;lt;/code&amp;gt;&lt;br /&gt;
| Clearer and more descriptive and is consistent with the other get method&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;&lt;br /&gt;
| Describes both creation and authorization setup of participant to assignment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_user_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt;&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_assignment_participants&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Improve Documentation and Comments==&lt;br /&gt;
&lt;br /&gt;
Some of the documentation and in-line comments can be somewhat vague. This can lead to misconceptions about how some functions work or how some of the code can function. Below are potential improvements we plan to make for function descriptions, though these may change with the final implementation.&lt;br /&gt;
&lt;br /&gt;
=== Improved Method Comments ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Original Comment&lt;br /&gt;
! Refactored Comment&lt;br /&gt;
|-&lt;br /&gt;
| list_user_participants&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
| Retrieves all participants associated with the specified user ID&lt;br /&gt;
|-&lt;br /&gt;
| list_assignment_participants&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
| Retrieves all participants linked to the specified assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
| Fetch and return the participant with the given ID&lt;br /&gt;
|-&lt;br /&gt;
| add&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
| Creates a new participant for a given assignment and assigns appropriate authorization and permissions&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
| Updates the participant’s authorization role and related permissions&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
| Deletes the participant identified by the given ID and returns a confirmation message&lt;br /&gt;
|-&lt;br /&gt;
| participant_params&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
| Strong parameters: list of attributes allowed for participant creation or update&lt;br /&gt;
|-&lt;br /&gt;
| filter_user_participants&lt;br /&gt;
| Filters participants based on the provided user. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by user, if provided&lt;br /&gt;
|-&lt;br /&gt;
| filter_assignment_participants&lt;br /&gt;
| Filters participants based on the provided assignment. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by assignment, if provided&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| Validates that the authorization parameter is present and is one of the following valid authorizations: reader, reviewer, submitter, mentor&lt;br /&gt;
| Ensures authorization param is valid and returns it in lowercase; otherwise returns error response&lt;br /&gt;
|-&lt;br /&gt;
| find_user / find_assignment / find_participant&lt;br /&gt;
| Finds a user/assignment/participant by ID and returns it&lt;br /&gt;
| Fetches the corresponding record by ID; renders a not-found error if record does not exist&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Proposed Testing Changes==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add more descriptive comments for tests&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that authorizations are updated correctly&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that inputted path parameters are not missing and valid inputs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Tests at Line 222 and Line 231 are redundant, as the only difference in the test is the authorization, which would not affect what happens if a participant is not found&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
As this is a refactoring project, most of our work on the codebase involved cleaning up the current codebase to better align with foundational code style principles rather than introducing any of kind of new functionality. Our primary focus is to make the code more readable and easier to work with than before. We also took the liberty of fixing some minor errors that we found along the way.&lt;br /&gt;
&lt;br /&gt;
==Changelog==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Naming changes to multiple functions for better clarity and consistency&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Changed HTML status message for &amp;lt;code&amp;gt;show()&amp;lt;/code&amp;gt; from 201 (Created) to 200 (OK) as it is a better fit&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Created the &amp;lt;code&amp;gt;assign_participant_permissions()&amp;lt;/code&amp;gt; method&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Introduced two additional tests and removed a redundant one (see Testing Plan for more details)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Removed redundant queries to &amp;lt;code&amp;gt;Participant.all()&amp;lt;/code&amp;gt; in both filtering methods&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Updated method comments to be more descriptive (see comments table in Design)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Function Name Changes==&lt;br /&gt;
&lt;br /&gt;
The previous implementation had several functions that were strangely named or had names that could be easily misconstrued. The name changes remain the same from the proposal and design section, but for the purpose of clarity, the rationale for each of the functions will be provided below.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;list_user_participants&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
These two functions are meant to return a list of participants given a &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt; respectively. Based on the name alone, it is difficult to tell that the function would return a User/Assignment or Participants. In order to remedy this, we chose the names &amp;lt;code&amp;gt;get_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;get_participants_by_assignment&amp;lt;/code&amp;gt;. The word &amp;quot;list&amp;quot; was replaced by &amp;quot;get&amp;quot; in order to better denote that it is returning something and the &amp;quot;by&amp;quot; is added to emphasize that the User and Assignment are being used as parameters to search for the Participants. This provides a much clearer picture of what these functions should do compared to before.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; function's name was too vague to be particularly useful in identifying its purpose. To be more accurate, the function was meant to add the user to a given assignment, which would return a participant from the assignment's &amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; function. The new name of the function provides much more context to what it does (&amp;lt;code&amp;gt;add_participant_to_assignment&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;filter_user_participants&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_assignment_participants&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Similar to the list methods that were previously mentioned, it is difficult to tell what exactly these two functions do. While it can be easily seen that it filters something, what is being filtered can be easily mistaken (e.g. does it filter users by participants or participants by users?). The new names, &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt; are much clearer in defining that the User and Assignment are being used as the filter parameters for the function.&lt;br /&gt;
&lt;br /&gt;
==HTML Status Code Change for &amp;lt;code&amp;gt;GET&amp;lt;/code&amp;gt; Call==&lt;br /&gt;
&lt;br /&gt;
The status code being used for this was previously 201, denoting &amp;quot;successful creation&amp;quot;. We have corrected this to a simple 200 code, which signifies an &amp;quot;ok&amp;quot; status message. This issue was actually identified by ChatGPT while we were dowsing for potential issues.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Test modified&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# Tests whether a participant returns properly if provided with a valid Participant ID&lt;br /&gt;
response '200', 'Returns a participant' do&lt;br /&gt;
  let(:id) { participant2.id }&lt;br /&gt;
&lt;br /&gt;
  run_test! do |response|&lt;br /&gt;
    data = JSON.parse(response.body)&lt;br /&gt;
    expect(data['user_id']).to eq(studenta.id)&lt;br /&gt;
    expect(data['assignment_id']).to eq(assignment2.id)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Redundant &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; Queries Removed==&lt;br /&gt;
&lt;br /&gt;
This issue was initially caught by the LLM, ChatGPT, that the team was using in order to find potential issues. We found that simply using &amp;lt;code&amp;gt;Participant.where()&amp;lt;/code&amp;gt; removed the need for the &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; query entirely while changing nothing else about the function, reducing the amount of queries necessary to call the filtering methods, &amp;lt;code&amp;gt;filter_participants_by_user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter_participants_by_assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# New function&lt;br /&gt;
def filter_participants_by_user(user)&lt;br /&gt;
  participants = Participant.where(user_id: user.id) if user # This would simply get the participants given the proper user ID&lt;br /&gt;
  participants.order(:id)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# Old function&lt;br /&gt;
def filter_participants_by_user(user)&lt;br /&gt;
  participants = Participant.all() # This would obtain the entire list of participants rather than just the necessary ones&lt;br /&gt;
  participants = participants.where(user_id: user.id) if user&lt;br /&gt;
  participants.order(:id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==New Private Method: &amp;lt;code&amp;gt;assign_participant_permissions()&amp;lt;/code&amp;gt;==&lt;br /&gt;
&lt;br /&gt;
The reasoning behind the addition of this method is because of a repeated piece of code that existed in the previous implementation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
participant.authorization = authorization&lt;br /&gt;
participant.can_submit = permissions[:can_submit]&lt;br /&gt;
participant.can_review = permissions[:can_review]&lt;br /&gt;
participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This was repeated in two different contexts: when the Participant was updated or created. This is a violation of the DRY principle, as the same code is repeated multiple times where it could have been reduced to make it more easily readable. In order to resolve this issue, we simply turned this code snippet into a private method that can be called within &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
  # An authorization string containing the participant's role is taken and used to determine&lt;br /&gt;
  # what permissions will be allocated to the participant. Each of these permissions will&lt;br /&gt;
  # then be assigned to the Participant's database permission attributes.&lt;br /&gt;
  #&lt;br /&gt;
  # @param [String] authorization: An authorization string that represents the participant's role&lt;br /&gt;
  # @param [Participant] participant: The participant whose authorization permissions are being updated&lt;br /&gt;
  def assign_participant_permissions(authorization, participant)&lt;br /&gt;
    # Call helper method from participants_helper to retrieve a dictionary containing the&lt;br /&gt;
    # appropriate permission boolean values for the role specified by the authorization string&lt;br /&gt;
    permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
    # Assigns each of the boolean permission values to their respective database counterparts&lt;br /&gt;
    participant.authorization = authorization&lt;br /&gt;
    participant.can_submit = permissions[:can_submit]&lt;br /&gt;
    participant.can_review = permissions[:can_review]&lt;br /&gt;
    participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
    participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Description:===&lt;br /&gt;
&lt;br /&gt;
An authorization string containing the participant's role is taken and used to determine what permissions will be allocated to the participant. Each of these permissions will then be assigned to the Participant's database permission attributes.&lt;br /&gt;
&lt;br /&gt;
===Parameters:===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt;: An authorization string that represents the participant's role. This can be either reader, reviewer, submitter, or mentor.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;code&amp;gt;participant&amp;lt;/code&amp;gt;: The participant whose attributes are being updated. This is passed in to be modified by the function to be used to assign each of the participant's attribute values that are representative of its assigned role.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Behavior===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Use &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;participants_helper&amp;lt;/code&amp;gt; in order to get all necessary permission boolean values for a given participant role&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Assign each of the permission boolean values (&amp;lt;code&amp;gt;can_submit&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_review&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_take_quiz&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;can_mentor&amp;lt;/code&amp;gt;)&amp;lt;/li&amp;gt; from the helper method to their respective database attribute counterparts in Participant&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Testing Plan=&lt;br /&gt;
&lt;br /&gt;
From the previous implementation, there are 24 tests that are all passing. For more information about the previous testing plan, please refer to the previous implementation's page here: [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2484._Reimplement_participants_controller.rb]&lt;br /&gt;
&lt;br /&gt;
Below are any modifications to the existing test file (&amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt;) that we have made during the course of this project, alongside the descriptions and rationales behind them:&lt;br /&gt;
&lt;br /&gt;
==New Tests==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 25 || Check whether &amp;lt;code&amp;gt;Participant&amp;lt;/code&amp;gt; properly assigns the appropriate permissions when updating authorizations to each new role&lt;br /&gt;
|-&lt;br /&gt;
| 26 || Check the validity of incoming path parameters (Invalid: Non-Existent)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Modified Tests==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Status !! Modification Description &lt;br /&gt;
|-&lt;br /&gt;
| 22 || Removed || This test was removed as it was redundant. While it is important to check the authorization of the participant that would be invalid, the invalid ID used for this test is a duplicate of the previous test, meaning the result is guaranteed to match that of the previous test regardless of what is meant to be tested.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Next Steps=&lt;br /&gt;
&lt;br /&gt;
Of the proposed designs made at the beginning of the project, we were ultimately unable to implement one of our ideas to reduce the amount of repetition in the code. Being able to implement this could potentially simplify rendering to the view somewhat in that it could handle simple HTML status code handling. The likely cause a lack of full understanding regarding the fundamentals of Ruby. Below are some failed examples as to what we tried to implement to serve as a point of reference:&lt;br /&gt;
&lt;br /&gt;
===Example 1===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
# Checks if a target object (participant or participants) is not nil and then renders the object.&lt;br /&gt;
# If the object is nil, renders the object errors and sends a not_found_status and if the object&lt;br /&gt;
# exists, renders the object and sends a success status&lt;br /&gt;
# not_found_status default: :unprocessable_entity (422)&lt;br /&gt;
# success_status default: :ok (200)&lt;br /&gt;
def render_object_or_error(object, not_found_status: :unprocessable_entity, success_status: :ok)&lt;br /&gt;
  if object.nil?&lt;br /&gt;
    render json: { error: 'Resource not found' }, status: not_found_status&lt;br /&gt;
  elsif object.respond_to?(:errors) &amp;amp;&amp;amp; object.errors.any?&lt;br /&gt;
    render json: object.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: object, status: success_status&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example is modeled to be specific to the most common use case for this function in the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; by returning the default 422 and 200 error and success codes that are used by three instances of JSON rendering where it checks for whether a list of participants or a single participant is nil. These default values for the status codes are mainly to cover those instances, but could be changed to something else if necessary. The &amp;lt;code&amp;gt;object&amp;lt;/code&amp;gt; parameter is representative of the object that was meant to be rendered given the success or failure of the operation.&lt;br /&gt;
&lt;br /&gt;
===Example 2===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
def render_object_if(conditional, object, error_status, success_status)&lt;br /&gt;
  if conditional&lt;br /&gt;
    render json: { error: 'Resource not found' }, status: error_status&lt;br /&gt;
  else&lt;br /&gt;
    render json: object, status: success_status&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example is a more generic implementation of the function, mandating the error and success status codes rather than providing default values. The point of this was to emphasize readability when glancing over the use of this function. For example, being able to tell that seeing the function being used would immediately tell the reader what the success and failure states were immediately without having to find and inspect the function itself. The &amp;lt;code&amp;gt;conditional&amp;lt;/code&amp;gt; parameter would also allow the function to act similarly to a more readable ternary statement made for rendering.&lt;br /&gt;
&lt;br /&gt;
Implementing this successfully would reduce the amount of repetitive code being used within the controller, as the if-else view rendering is very common in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. We were unable to implement it within our given timeframe, so we opted to divert our focus on other, important tasks that we needed to do.&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Relevant Links =&lt;br /&gt;
&lt;br /&gt;
Pull Request [https://github.com/expertiza/reimplementation-back-end/pull/192] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163888</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163888"/>
		<updated>2025-04-08T21:49:07Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Improved Method Comments */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
==Use of Large Language Models (LLMs)==&lt;br /&gt;
&lt;br /&gt;
For this project, we are using ChatGPT as an LLM helper in determining what issues there are within the code. The use of LLMs in this project will likely be limited to probing for potential issues that exist within the system.&lt;br /&gt;
&lt;br /&gt;
Below we have organized the following prompts and a summary of the output in a table:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 25%&amp;quot; | Prompts !! LLM Output Summary&lt;br /&gt;
|-&lt;br /&gt;
| [Code from &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;]&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt; Are there any ways where we can refactor the code to improve readability, DRYness, and clarity of error handling?&lt;br /&gt;
|| It recognized some of the issues we, as a team, had already identified and suggested fixes that were similar to what we outlined: &amp;lt;b&amp;gt;Redundant JSON Rendering Code&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_Redundant_JSON_Rendering_Code] and &amp;lt;b&amp;gt;Simplifying the Assignment of Participant Fields&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_the_Assignment_of_Participant_Fields]. Additionally, it suggested minor changes that we could implement, such as using &amp;lt;code&amp;gt;Participant.where(...)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; to filter out the code more efficiently instead of getting all database instances every time, as well as the use of strong parameters in &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update_authorization()&amp;lt;/code&amp;gt; to avoid having to implement custom parsing techniques. It also recommends renaming the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; function to something more specific in relation to its purpose (adding a &amp;lt;code&amp;gt;Participant&amp;lt;/code&amp;gt; to an &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Potential Redundant Tests in &amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|| The tests on line 222 and 231 are redundant as only the authorization differs. (Note: This should be investigated to see whether or not this is necessary)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed information on what prompts we used and the output we got, please visit the page here: [https://docs.google.com/document/d/105_U_Coky-edx7n-tFhD2B5RqmVXxEsKPW_qUaf7bQU/edit?usp=sharing].&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Some API functions are not returning the correct HTML status messages (e.g. test on line 136 returns 201 instead of 200)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Documentation and comments can be somewhat vague&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;In-line comments should be more descriptive, explaining what the code does in more details&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Tests are not described via comments, but in name alone; some more descriptive comments that explain the tests in more detail would be ideal&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution (TEMP)==&lt;br /&gt;
&lt;br /&gt;
===Simplifying Redundant JSON Rendering Code===&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Simplifying the Assignment of Participant Fields===&lt;br /&gt;
&lt;br /&gt;
In the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Provide More Clarity in Function Names===&lt;br /&gt;
&lt;br /&gt;
There are some functions that are somewhat unclear/vague in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. For example, the &amp;lt;code&amp;gt;list_user_participants()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== - Suggested Method Name Improvements ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Old Method Name&lt;br /&gt;
! New Method Name&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| list_user_participants&lt;br /&gt;
| participants_by_user&lt;br /&gt;
| Clearer and more descriptive&lt;br /&gt;
|-&lt;br /&gt;
| list_assignment_participants&lt;br /&gt;
| participants_by_assignment&lt;br /&gt;
| Consistent with the above&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| show_participant&lt;br /&gt;
| Explicit about what is shown&lt;br /&gt;
|-&lt;br /&gt;
| add&lt;br /&gt;
| create_participant_with_authorization&lt;br /&gt;
| Describes both creation and auth setup&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| update_participant_authorization&lt;br /&gt;
| Makes the subject (participant) clear&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| destroy_participant&lt;br /&gt;
| More descriptive for further use&lt;br /&gt;
|-&lt;br /&gt;
| filter_user_participants&lt;br /&gt;
| participants_for_user&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| filter_assignment_participants&lt;br /&gt;
| participants_for_assignment&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| validated_authorization&lt;br /&gt;
| Suggests return value is validated&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Improve Documentation and Comments===&lt;br /&gt;
&lt;br /&gt;
=== Improved Method Comments ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Original Comment&lt;br /&gt;
! Refactored Comment&lt;br /&gt;
|-&lt;br /&gt;
| list_user_participants&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
| Retrieves all participants associated with the specified user ID&lt;br /&gt;
|-&lt;br /&gt;
| list_assignment_participants&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
| Retrieves all participants linked to the specified assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
| Fetch and return the participant with the given ID&lt;br /&gt;
|-&lt;br /&gt;
| add&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
| Creates a new participant for a given assignment and assigns appropriate authorization and permissions&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
| Updates the participant’s authorization role and related permissions&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
| Deletes the participant identified by the given ID and returns a confirmation message&lt;br /&gt;
|-&lt;br /&gt;
| participant_params&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
| Strong parameters: list of attributes allowed for participant creation or update&lt;br /&gt;
|-&lt;br /&gt;
| filter_user_participants&lt;br /&gt;
| Filters participants based on the provided user. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by user, if provided&lt;br /&gt;
|-&lt;br /&gt;
| filter_assignment_participants&lt;br /&gt;
| Filters participants based on the provided assignment. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by assignment, if provided&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| Validates that the authorization parameter is present and is one of the following valid authorizations: reader, reviewer, submitter, mentor&lt;br /&gt;
| Ensures authorization param is valid and returns it in lowercase; otherwise returns error response&lt;br /&gt;
|-&lt;br /&gt;
| find_user / find_assignment / find_participant&lt;br /&gt;
| Finds a user/assignment/participant by ID and returns it&lt;br /&gt;
| Fetches the corresponding record by ID; renders a not-found error if record does not exist&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Proposed Testing Changes===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add more descriptive comments for tests&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that authorizations are updated correctly&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that inputted path parameters are not missing and valid inputs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Tests at Line 222 and Line 231 are redundant, as the only difference in the test is the authorization, which would not affect what happens if a participant is not found&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
&lt;br /&gt;
Pull Request (Unimplemented) [] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163887</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163887"/>
		<updated>2025-04-08T21:48:25Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Testing Plan (TEMP) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
==Use of Large Language Models (LLMs)==&lt;br /&gt;
&lt;br /&gt;
For this project, we are using ChatGPT as an LLM helper in determining what issues there are within the code. The use of LLMs in this project will likely be limited to probing for potential issues that exist within the system.&lt;br /&gt;
&lt;br /&gt;
Below we have organized the following prompts and a summary of the output in a table:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 25%&amp;quot; | Prompts !! LLM Output Summary&lt;br /&gt;
|-&lt;br /&gt;
| [Code from &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;]&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt; Are there any ways where we can refactor the code to improve readability, DRYness, and clarity of error handling?&lt;br /&gt;
|| It recognized some of the issues we, as a team, had already identified and suggested fixes that were similar to what we outlined: &amp;lt;b&amp;gt;Redundant JSON Rendering Code&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_Redundant_JSON_Rendering_Code] and &amp;lt;b&amp;gt;Simplifying the Assignment of Participant Fields&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_the_Assignment_of_Participant_Fields]. Additionally, it suggested minor changes that we could implement, such as using &amp;lt;code&amp;gt;Participant.where(...)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; to filter out the code more efficiently instead of getting all database instances every time, as well as the use of strong parameters in &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update_authorization()&amp;lt;/code&amp;gt; to avoid having to implement custom parsing techniques. It also recommends renaming the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; function to something more specific in relation to its purpose (adding a &amp;lt;code&amp;gt;Participant&amp;lt;/code&amp;gt; to an &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Potential Redundant Tests in &amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|| The tests on line 222 and 231 are redundant as only the authorization differs. (Note: This should be investigated to see whether or not this is necessary)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed information on what prompts we used and the output we got, please visit the page here: [https://docs.google.com/document/d/105_U_Coky-edx7n-tFhD2B5RqmVXxEsKPW_qUaf7bQU/edit?usp=sharing].&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Some API functions are not returning the correct HTML status messages (e.g. test on line 136 returns 201 instead of 200)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Documentation and comments can be somewhat vague&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;In-line comments should be more descriptive, explaining what the code does in more details&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Tests are not described via comments, but in name alone; some more descriptive comments that explain the tests in more detail would be ideal&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution (TEMP)==&lt;br /&gt;
&lt;br /&gt;
===Simplifying Redundant JSON Rendering Code===&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Simplifying the Assignment of Participant Fields===&lt;br /&gt;
&lt;br /&gt;
In the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Provide More Clarity in Function Names===&lt;br /&gt;
&lt;br /&gt;
There are some functions that are somewhat unclear/vague in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. For example, the &amp;lt;code&amp;gt;list_user_participants()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== - Suggested Method Name Improvements ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Old Method Name&lt;br /&gt;
! New Method Name&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| list_user_participants&lt;br /&gt;
| participants_by_user&lt;br /&gt;
| Clearer and more descriptive&lt;br /&gt;
|-&lt;br /&gt;
| list_assignment_participants&lt;br /&gt;
| participants_by_assignment&lt;br /&gt;
| Consistent with the above&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| show_participant&lt;br /&gt;
| Explicit about what is shown&lt;br /&gt;
|-&lt;br /&gt;
| add&lt;br /&gt;
| create_participant_with_authorization&lt;br /&gt;
| Describes both creation and auth setup&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| update_participant_authorization&lt;br /&gt;
| Makes the subject (participant) clear&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| destroy_participant&lt;br /&gt;
| More descriptive for further use&lt;br /&gt;
|-&lt;br /&gt;
| filter_user_participants&lt;br /&gt;
| participants_for_user&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| filter_assignment_participants&lt;br /&gt;
| participants_for_assignment&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| validated_authorization&lt;br /&gt;
| Suggests return value is validated&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Improve Documentation and Comments===&lt;br /&gt;
&lt;br /&gt;
== Improved Method Comments ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Original Comment&lt;br /&gt;
! Refactored Comment&lt;br /&gt;
|-&lt;br /&gt;
| list_user_participants&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
| Retrieves all participants associated with the specified user ID&lt;br /&gt;
|-&lt;br /&gt;
| list_assignment_participants&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
| Retrieves all participants linked to the specified assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
| Fetch and return the participant with the given ID&lt;br /&gt;
|-&lt;br /&gt;
| add&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
| Creates a new participant for a given assignment and assigns appropriate authorization and permissions&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
| Updates the participant’s authorization role and related permissions&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
| Deletes the participant identified by the given ID and returns a confirmation message&lt;br /&gt;
|-&lt;br /&gt;
| participant_params&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
| Strong parameters: list of attributes allowed for participant creation or update&lt;br /&gt;
|-&lt;br /&gt;
| filter_user_participants&lt;br /&gt;
| Filters participants based on the provided user. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by user, if provided&lt;br /&gt;
|-&lt;br /&gt;
| filter_assignment_participants&lt;br /&gt;
| Filters participants based on the provided assignment. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by assignment, if provided&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| Validates that the authorization parameter is present and is one of the following valid authorizations: reader, reviewer, submitter, mentor&lt;br /&gt;
| Ensures authorization param is valid and returns it in lowercase; otherwise returns error response&lt;br /&gt;
|-&lt;br /&gt;
| find_user / find_assignment / find_participant&lt;br /&gt;
| Finds a user/assignment/participant by ID and returns it&lt;br /&gt;
| Fetches the corresponding record by ID; renders a not-found error if record does not exist&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Proposed Testing Changes===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add more descriptive comments for tests&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that authorizations are updated correctly&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that inputted path parameters are not missing and valid inputs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Tests at Line 222 and Line 231 are redundant, as the only difference in the test is the authorization, which would not affect what happens if a participant is not found&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
&lt;br /&gt;
Pull Request (Unimplemented) [] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163886</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163886"/>
		<updated>2025-04-08T21:47:49Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Next Steps (TEMP) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
==Use of Large Language Models (LLMs)==&lt;br /&gt;
&lt;br /&gt;
For this project, we are using ChatGPT as an LLM helper in determining what issues there are within the code. The use of LLMs in this project will likely be limited to probing for potential issues that exist within the system.&lt;br /&gt;
&lt;br /&gt;
Below we have organized the following prompts and a summary of the output in a table:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 25%&amp;quot; | Prompts !! LLM Output Summary&lt;br /&gt;
|-&lt;br /&gt;
| [Code from &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;]&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt; Are there any ways where we can refactor the code to improve readability, DRYness, and clarity of error handling?&lt;br /&gt;
|| It recognized some of the issues we, as a team, had already identified and suggested fixes that were similar to what we outlined: &amp;lt;b&amp;gt;Redundant JSON Rendering Code&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_Redundant_JSON_Rendering_Code] and &amp;lt;b&amp;gt;Simplifying the Assignment of Participant Fields&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_the_Assignment_of_Participant_Fields]. Additionally, it suggested minor changes that we could implement, such as using &amp;lt;code&amp;gt;Participant.where(...)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; to filter out the code more efficiently instead of getting all database instances every time, as well as the use of strong parameters in &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update_authorization()&amp;lt;/code&amp;gt; to avoid having to implement custom parsing techniques. It also recommends renaming the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; function to something more specific in relation to its purpose (adding a &amp;lt;code&amp;gt;Participant&amp;lt;/code&amp;gt; to an &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Potential Redundant Tests in &amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|| The tests on line 222 and 231 are redundant as only the authorization differs. (Note: This should be investigated to see whether or not this is necessary)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed information on what prompts we used and the output we got, please visit the page here: [https://docs.google.com/document/d/105_U_Coky-edx7n-tFhD2B5RqmVXxEsKPW_qUaf7bQU/edit?usp=sharing].&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Some API functions are not returning the correct HTML status messages (e.g. test on line 136 returns 201 instead of 200)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Documentation and comments can be somewhat vague&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;In-line comments should be more descriptive, explaining what the code does in more details&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Tests are not described via comments, but in name alone; some more descriptive comments that explain the tests in more detail would be ideal&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution (TEMP)==&lt;br /&gt;
&lt;br /&gt;
===Simplifying Redundant JSON Rendering Code===&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Simplifying the Assignment of Participant Fields===&lt;br /&gt;
&lt;br /&gt;
In the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Provide More Clarity in Function Names===&lt;br /&gt;
&lt;br /&gt;
There are some functions that are somewhat unclear/vague in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. For example, the &amp;lt;code&amp;gt;list_user_participants()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== - Suggested Method Name Improvements ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Old Method Name&lt;br /&gt;
! New Method Name&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| list_user_participants&lt;br /&gt;
| participants_by_user&lt;br /&gt;
| Clearer and more descriptive&lt;br /&gt;
|-&lt;br /&gt;
| list_assignment_participants&lt;br /&gt;
| participants_by_assignment&lt;br /&gt;
| Consistent with the above&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| show_participant&lt;br /&gt;
| Explicit about what is shown&lt;br /&gt;
|-&lt;br /&gt;
| add&lt;br /&gt;
| create_participant_with_authorization&lt;br /&gt;
| Describes both creation and auth setup&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| update_participant_authorization&lt;br /&gt;
| Makes the subject (participant) clear&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| destroy_participant&lt;br /&gt;
| More descriptive for further use&lt;br /&gt;
|-&lt;br /&gt;
| filter_user_participants&lt;br /&gt;
| participants_for_user&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| filter_assignment_participants&lt;br /&gt;
| participants_for_assignment&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| validated_authorization&lt;br /&gt;
| Suggests return value is validated&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Improve Documentation and Comments===&lt;br /&gt;
&lt;br /&gt;
== Improved Method Comments ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Original Comment&lt;br /&gt;
! Refactored Comment&lt;br /&gt;
|-&lt;br /&gt;
| list_user_participants&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
| Retrieves all participants associated with the specified user ID&lt;br /&gt;
|-&lt;br /&gt;
| list_assignment_participants&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
| Retrieves all participants linked to the specified assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
| Fetch and return the participant with the given ID&lt;br /&gt;
|-&lt;br /&gt;
| add&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
| Creates a new participant for a given assignment and assigns appropriate authorization and permissions&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
| Updates the participant’s authorization role and related permissions&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
| Deletes the participant identified by the given ID and returns a confirmation message&lt;br /&gt;
|-&lt;br /&gt;
| participant_params&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
| Strong parameters: list of attributes allowed for participant creation or update&lt;br /&gt;
|-&lt;br /&gt;
| filter_user_participants&lt;br /&gt;
| Filters participants based on the provided user. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by user, if provided&lt;br /&gt;
|-&lt;br /&gt;
| filter_assignment_participants&lt;br /&gt;
| Filters participants based on the provided assignment. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by assignment, if provided&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| Validates that the authorization parameter is present and is one of the following valid authorizations: reader, reviewer, submitter, mentor&lt;br /&gt;
| Ensures authorization param is valid and returns it in lowercase; otherwise returns error response&lt;br /&gt;
|-&lt;br /&gt;
| find_user / find_assignment / find_participant&lt;br /&gt;
| Finds a user/assignment/participant by ID and returns it&lt;br /&gt;
| Fetches the corresponding record by ID; renders a not-found error if record does not exist&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Proposed Testing Changes===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add more descriptive comments for tests&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that authorizations are updated correctly&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that inputted path parameters are not missing and valid inputs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Tests at Line 222 and Line 231 are redundant, as the only difference in the test is the authorization, which would not affect what happens if a participant is not found&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Plan (TEMP)==&lt;br /&gt;
&lt;br /&gt;
From the previous implementation, there are 24 tests that are all passing. For more information about the previous testing plan, please refer to the previous implementation's page here: [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2484._Reimplement_participants_controller.rb]&lt;br /&gt;
&lt;br /&gt;
===New/Modified Tests===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 25 || Check whether &amp;lt;code&amp;gt;Participant&amp;lt;/code&amp;gt; properly assigns the appropriate permissions when updating authorizations to each new role&lt;br /&gt;
|-&lt;br /&gt;
| 26 || Check the validity of incoming path parameters (Invalid: Non-Existent)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
&lt;br /&gt;
Pull Request (Unimplemented) [] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163885</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163885"/>
		<updated>2025-04-08T21:47:26Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Implementation (TEMP) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
==Use of Large Language Models (LLMs)==&lt;br /&gt;
&lt;br /&gt;
For this project, we are using ChatGPT as an LLM helper in determining what issues there are within the code. The use of LLMs in this project will likely be limited to probing for potential issues that exist within the system.&lt;br /&gt;
&lt;br /&gt;
Below we have organized the following prompts and a summary of the output in a table:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 25%&amp;quot; | Prompts !! LLM Output Summary&lt;br /&gt;
|-&lt;br /&gt;
| [Code from &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;]&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt; Are there any ways where we can refactor the code to improve readability, DRYness, and clarity of error handling?&lt;br /&gt;
|| It recognized some of the issues we, as a team, had already identified and suggested fixes that were similar to what we outlined: &amp;lt;b&amp;gt;Redundant JSON Rendering Code&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_Redundant_JSON_Rendering_Code] and &amp;lt;b&amp;gt;Simplifying the Assignment of Participant Fields&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_the_Assignment_of_Participant_Fields]. Additionally, it suggested minor changes that we could implement, such as using &amp;lt;code&amp;gt;Participant.where(...)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; to filter out the code more efficiently instead of getting all database instances every time, as well as the use of strong parameters in &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update_authorization()&amp;lt;/code&amp;gt; to avoid having to implement custom parsing techniques. It also recommends renaming the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; function to something more specific in relation to its purpose (adding a &amp;lt;code&amp;gt;Participant&amp;lt;/code&amp;gt; to an &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Potential Redundant Tests in &amp;lt;code&amp;gt;participants_controller_spec.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|| The tests on line 222 and 231 are redundant as only the authorization differs. (Note: This should be investigated to see whether or not this is necessary)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed information on what prompts we used and the output we got, please visit the page here: [https://docs.google.com/document/d/105_U_Coky-edx7n-tFhD2B5RqmVXxEsKPW_qUaf7bQU/edit?usp=sharing].&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Some API functions are not returning the correct HTML status messages (e.g. test on line 136 returns 201 instead of 200)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Documentation and comments can be somewhat vague&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;In-line comments should be more descriptive, explaining what the code does in more details&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Tests are not described via comments, but in name alone; some more descriptive comments that explain the tests in more detail would be ideal&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution (TEMP)==&lt;br /&gt;
&lt;br /&gt;
===Simplifying Redundant JSON Rendering Code===&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Simplifying the Assignment of Participant Fields===&lt;br /&gt;
&lt;br /&gt;
In the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Provide More Clarity in Function Names===&lt;br /&gt;
&lt;br /&gt;
There are some functions that are somewhat unclear/vague in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. For example, the &amp;lt;code&amp;gt;list_user_participants()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== - Suggested Method Name Improvements ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Old Method Name&lt;br /&gt;
! New Method Name&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| list_user_participants&lt;br /&gt;
| participants_by_user&lt;br /&gt;
| Clearer and more descriptive&lt;br /&gt;
|-&lt;br /&gt;
| list_assignment_participants&lt;br /&gt;
| participants_by_assignment&lt;br /&gt;
| Consistent with the above&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| show_participant&lt;br /&gt;
| Explicit about what is shown&lt;br /&gt;
|-&lt;br /&gt;
| add&lt;br /&gt;
| create_participant_with_authorization&lt;br /&gt;
| Describes both creation and auth setup&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| update_participant_authorization&lt;br /&gt;
| Makes the subject (participant) clear&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| destroy_participant&lt;br /&gt;
| More descriptive for further use&lt;br /&gt;
|-&lt;br /&gt;
| filter_user_participants&lt;br /&gt;
| participants_for_user&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| filter_assignment_participants&lt;br /&gt;
| participants_for_assignment&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| validated_authorization&lt;br /&gt;
| Suggests return value is validated&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Improve Documentation and Comments===&lt;br /&gt;
&lt;br /&gt;
== Improved Method Comments ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Original Comment&lt;br /&gt;
! Refactored Comment&lt;br /&gt;
|-&lt;br /&gt;
| list_user_participants&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
| Retrieves all participants associated with the specified user ID&lt;br /&gt;
|-&lt;br /&gt;
| list_assignment_participants&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
| Retrieves all participants linked to the specified assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
| Fetch and return the participant with the given ID&lt;br /&gt;
|-&lt;br /&gt;
| add&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
| Creates a new participant for a given assignment and assigns appropriate authorization and permissions&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
| Updates the participant’s authorization role and related permissions&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
| Deletes the participant identified by the given ID and returns a confirmation message&lt;br /&gt;
|-&lt;br /&gt;
| participant_params&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
| Strong parameters: list of attributes allowed for participant creation or update&lt;br /&gt;
|-&lt;br /&gt;
| filter_user_participants&lt;br /&gt;
| Filters participants based on the provided user. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by user, if provided&lt;br /&gt;
|-&lt;br /&gt;
| filter_assignment_participants&lt;br /&gt;
| Filters participants based on the provided assignment. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by assignment, if provided&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| Validates that the authorization parameter is present and is one of the following valid authorizations: reader, reviewer, submitter, mentor&lt;br /&gt;
| Ensures authorization param is valid and returns it in lowercase; otherwise returns error response&lt;br /&gt;
|-&lt;br /&gt;
| find_user / find_assignment / find_participant&lt;br /&gt;
| Finds a user/assignment/participant by ID and returns it&lt;br /&gt;
| Fetches the corresponding record by ID; renders a not-found error if record does not exist&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Proposed Testing Changes===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add more descriptive comments for tests&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that authorizations are updated correctly&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that inputted path parameters are not missing and valid inputs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Tests at Line 222 and Line 231 are redundant, as the only difference in the test is the authorization, which would not affect what happens if a participant is not found&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Plan (TEMP)==&lt;br /&gt;
&lt;br /&gt;
From the previous implementation, there are 24 tests that are all passing. For more information about the previous testing plan, please refer to the previous implementation's page here: [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2484._Reimplement_participants_controller.rb]&lt;br /&gt;
&lt;br /&gt;
===New/Modified Tests===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 25 || Check whether &amp;lt;code&amp;gt;Participant&amp;lt;/code&amp;gt; properly assigns the appropriate permissions when updating authorizations to each new role&lt;br /&gt;
|-&lt;br /&gt;
| 26 || Check the validity of incoming path parameters (Invalid: Non-Existent)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Next Steps (TEMP)==&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
&lt;br /&gt;
Pull Request (Unimplemented) [] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163873</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163873"/>
		<updated>2025-04-08T05:51:52Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Improve Documentation and Comments */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
==Use of Large Language Models (LLMs)==&lt;br /&gt;
&lt;br /&gt;
For this project, we are using ChatGPT as an LLM helper in determining what issues there are within the code.&lt;br /&gt;
&lt;br /&gt;
Below we have organized the following prompts and a summary of the output in a table:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 25%&amp;quot; | Prompts !! LLM Output &lt;br /&gt;
|-&lt;br /&gt;
| [Code from &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;]&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt; Are there any ways where we can refactor the code to improve readability, DRYness, and clarity of error handling? || It recognized some of the issues we, as a team, had already identified and suggested fixes that were similar to what we outlined: &amp;lt;b&amp;gt;Redundant JSON Rendering Code&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_Redundant_JSON_Rendering_Code] and &amp;lt;b&amp;gt;Simplifying the Assignment of Participant Fields&amp;lt;/b&amp;gt;[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb#Simplifying_the_Assignment_of_Participant_Fields]. Additionally, it suggested minor changes that we could implement, such as using &amp;lt;code&amp;gt;Participant.where(...)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;Participant.all&amp;lt;/code&amp;gt; to filter out the code more efficiently instead of getting all database instances every time, as well as the use of strong parameters in &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update_authorization()&amp;lt;/code&amp;gt; to avoid having to implement custom parsing techniques. It also recommends renaming the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; function to something more specific in relation to its purpose (adding a &amp;lt;code&amp;gt;Participant&amp;lt;/code&amp;gt; to an &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed information on what prompts we used and the output we got, please visit the page here: [https://docs.google.com/document/d/105_U_Coky-edx7n-tFhD2B5RqmVXxEsKPW_qUaf7bQU/edit?usp=sharing].&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Some API functions are not returning the correct HTML status messages (e.g. test on line 136 returns 201 instead of 200)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Documentation and comments can be somewhat vague&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;In-line comments should be more descriptive, explaining what the code does in more details&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Tests are not described via comments, but in name alone; some more descriptive comments that explain the tests in more detail would be ideal&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution (TEMP)==&lt;br /&gt;
&lt;br /&gt;
===Simplifying Redundant JSON Rendering Code===&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Simplifying the Assignment of Participant Fields===&lt;br /&gt;
&lt;br /&gt;
In the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Provide More Clarity in Function Names===&lt;br /&gt;
&lt;br /&gt;
There are some functions that are somewhat unclear/vague in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. For example, the &amp;lt;code&amp;gt;list_user_participants()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== - Suggested Method Name Improvements ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Old Method Name&lt;br /&gt;
! New Method Name&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| list_user_participants&lt;br /&gt;
| participants_by_user&lt;br /&gt;
| Clearer and more descriptive&lt;br /&gt;
|-&lt;br /&gt;
| list_assignment_participants&lt;br /&gt;
| participants_by_assignment&lt;br /&gt;
| Consistent with the above&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| show_participant&lt;br /&gt;
| Explicit about what is shown&lt;br /&gt;
|-&lt;br /&gt;
| add&lt;br /&gt;
| create_participant_with_authorization&lt;br /&gt;
| Describes both creation and auth setup&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| update_participant_authorization&lt;br /&gt;
| Makes the subject (participant) clear&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| destroy_participant&lt;br /&gt;
| More descriptive for further use&lt;br /&gt;
|-&lt;br /&gt;
| filter_user_participants&lt;br /&gt;
| participants_for_user&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| filter_assignment_participants&lt;br /&gt;
| participants_for_assignment&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| validated_authorization&lt;br /&gt;
| Suggests return value is validated&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Improve Documentation and Comments===&lt;br /&gt;
&lt;br /&gt;
== Improved Method Comments ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Original Comment&lt;br /&gt;
! Refactored Comment&lt;br /&gt;
|-&lt;br /&gt;
| list_user_participants&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
| Retrieves all participants associated with the specified user ID&lt;br /&gt;
|-&lt;br /&gt;
| list_assignment_participants&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
| Retrieves all participants linked to the specified assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
| Fetch and return the participant with the given ID&lt;br /&gt;
|-&lt;br /&gt;
| add&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
| Creates a new participant for a given assignment and assigns appropriate authorization and permissions&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
| Updates the participant’s authorization role and related permissions&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
| Deletes the participant identified by the given ID and returns a confirmation message&lt;br /&gt;
|-&lt;br /&gt;
| participant_params&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
| Strong parameters: list of attributes allowed for participant creation or update&lt;br /&gt;
|-&lt;br /&gt;
| filter_user_participants&lt;br /&gt;
| Filters participants based on the provided user. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by user, if provided&lt;br /&gt;
|-&lt;br /&gt;
| filter_assignment_participants&lt;br /&gt;
| Filters participants based on the provided assignment. Returns participants ordered by their IDs&lt;br /&gt;
| Returns a sorted list of participants filtered by assignment, if provided&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| Validates that the authorization parameter is present and is one of the following valid authorizations: reader, reviewer, submitter, mentor&lt;br /&gt;
| Ensures authorization param is valid and returns it in lowercase; otherwise returns error response&lt;br /&gt;
|-&lt;br /&gt;
| find_user / find_assignment / find_participant&lt;br /&gt;
| Finds a user/assignment/participant by ID and returns it&lt;br /&gt;
| Fetches the corresponding record by ID; renders a not-found error if record does not exist&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Proposed Testing Changes===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add more descriptive comments for tests&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that authorizations are updated correctly&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that inputted path parameters are not missing and valid inputs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Tests at Line 222 and Line 231 are redundant, as the only difference in the test is the authorization, which would not affect what happens if a participant is not found&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Implementation (TEMP)==&lt;br /&gt;
&lt;br /&gt;
==Testing Plan (TEMP)==&lt;br /&gt;
&lt;br /&gt;
From the previous implementation, there are 24 tests that are all passing. For more information about the previous testing plan, please refer to the previous implementation's page here: [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2484._Reimplement_participants_controller.rb]&lt;br /&gt;
&lt;br /&gt;
===New/Modified Tests===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (TEMP)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Next Steps (TEMP)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Key concerns identified include the overlap and redundancy within the current system:&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
&lt;br /&gt;
Pull Request (Unimplemented) [] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163871</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163871"/>
		<updated>2025-04-08T05:28:20Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Suggested Method Name Improvements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
==Use of Large Language Models (LLMs)==&lt;br /&gt;
&lt;br /&gt;
For this project, we are using ChatGPT as an LLM helper in determining what issues there are within the code.&lt;br /&gt;
&lt;br /&gt;
Below we have organized the following prompts and a summary of the output in a table:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Prompts !! LLM Output &lt;br /&gt;
|-&lt;br /&gt;
| [Code in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;] Are there any ways where we can refactor the code to improve readability, DRYness, and clarity of error handling? || It recognized some of the issues we, as a team, had already identified: &amp;lt;b&amp;gt;Redundant JSON Rendering Code&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;Simplifying the Assignment of Participant Fields&amp;lt;/b&amp;gt;. [IN PROGRESS]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed information on what prompts we used and the output we got, please visit the page here: [https://docs.google.com/document/d/105_U_Coky-edx7n-tFhD2B5RqmVXxEsKPW_qUaf7bQU/edit?usp=sharing].&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Some API functions are not returning the correct HTML status messages (e.g. test on line 136 returns 201 instead of 200)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Documentation and comments can be somewhat vague&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;In-line comments should be more descriptive, explaining what the code does in more details&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Tests are not described via comments, but in name alone; some more descriptive comments that explain the tests in more detail would be ideal&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution (TEMP)==&lt;br /&gt;
&lt;br /&gt;
===Simplifying Redundant JSON Rendering Code===&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Simplifying the Assignment of Participant Fields===&lt;br /&gt;
&lt;br /&gt;
In the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Provide More Clarity in Function Names===&lt;br /&gt;
&lt;br /&gt;
There are some functions that are somewhat unclear/vague in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. For example, the &amp;lt;code&amp;gt;list_user_participants()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== - Suggested Method Name Improvements ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Old Method Name&lt;br /&gt;
! New Method Name&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| list_user_participants&lt;br /&gt;
| participants_by_user&lt;br /&gt;
| Clearer and more descriptive&lt;br /&gt;
|-&lt;br /&gt;
| list_assignment_participants&lt;br /&gt;
| participants_by_assignment&lt;br /&gt;
| Consistent with the above&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| show_participant&lt;br /&gt;
| Explicit about what is shown&lt;br /&gt;
|-&lt;br /&gt;
| add&lt;br /&gt;
| create_participant_with_authorization&lt;br /&gt;
| Describes both creation and auth setup&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| update_participant_authorization&lt;br /&gt;
| Makes the subject (participant) clear&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| destroy_participant&lt;br /&gt;
| More descriptive for further use&lt;br /&gt;
|-&lt;br /&gt;
| filter_user_participants&lt;br /&gt;
| participants_for_user&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| filter_assignment_participants&lt;br /&gt;
| participants_for_assignment&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| validated_authorization&lt;br /&gt;
| Suggests return value is validated&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Improve Documentation and Comments===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Proposed Testing Changes===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add more descriptive comments for tests&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that authorizations are updated correctly&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that inputted path parameters are not missing and valid inputs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Tests at Line 222 and Line 231 are redundant, as the only difference in the test is the authorization, which would not affect what happens if a participant is not found&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Implementation (TEMP)==&lt;br /&gt;
&lt;br /&gt;
==Testing Plan (TEMP)==&lt;br /&gt;
&lt;br /&gt;
From the previous implementation, there are 24 tests that are all passing. For more information about the previous testing plan, please refer to the previous implementation's page here: [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2484._Reimplement_participants_controller.rb]&lt;br /&gt;
&lt;br /&gt;
===New/Modified Tests===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (TEMP)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Next Steps (TEMP)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Key concerns identified include the overlap and redundancy within the current system:&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
&lt;br /&gt;
Pull Request (Unimplemented) [] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163870</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163870"/>
		<updated>2025-04-08T05:28:10Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Suggested Method Name Improvements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
==Use of Large Language Models (LLMs)==&lt;br /&gt;
&lt;br /&gt;
For this project, we are using ChatGPT as an LLM helper in determining what issues there are within the code.&lt;br /&gt;
&lt;br /&gt;
Below we have organized the following prompts and a summary of the output in a table:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Prompts !! LLM Output &lt;br /&gt;
|-&lt;br /&gt;
| [Code in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;] Are there any ways where we can refactor the code to improve readability, DRYness, and clarity of error handling? || It recognized some of the issues we, as a team, had already identified: &amp;lt;b&amp;gt;Redundant JSON Rendering Code&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;Simplifying the Assignment of Participant Fields&amp;lt;/b&amp;gt;. [IN PROGRESS]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed information on what prompts we used and the output we got, please visit the page here: [https://docs.google.com/document/d/105_U_Coky-edx7n-tFhD2B5RqmVXxEsKPW_qUaf7bQU/edit?usp=sharing].&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Some API functions are not returning the correct HTML status messages (e.g. test on line 136 returns 201 instead of 200)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Documentation and comments can be somewhat vague&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;In-line comments should be more descriptive, explaining what the code does in more details&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Tests are not described via comments, but in name alone; some more descriptive comments that explain the tests in more detail would be ideal&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution (TEMP)==&lt;br /&gt;
&lt;br /&gt;
===Simplifying Redundant JSON Rendering Code===&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Simplifying the Assignment of Participant Fields===&lt;br /&gt;
&lt;br /&gt;
In the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Provide More Clarity in Function Names===&lt;br /&gt;
&lt;br /&gt;
There are some functions that are somewhat unclear/vague in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. For example, the &amp;lt;code&amp;gt;list_user_participants()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Suggested Method Name Improvements ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Old Method Name&lt;br /&gt;
! New Method Name&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| list_user_participants&lt;br /&gt;
| participants_by_user&lt;br /&gt;
| Clearer and more descriptive&lt;br /&gt;
|-&lt;br /&gt;
| list_assignment_participants&lt;br /&gt;
| participants_by_assignment&lt;br /&gt;
| Consistent with the above&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| show_participant&lt;br /&gt;
| Explicit about what is shown&lt;br /&gt;
|-&lt;br /&gt;
| add&lt;br /&gt;
| create_participant_with_authorization&lt;br /&gt;
| Describes both creation and auth setup&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| update_participant_authorization&lt;br /&gt;
| Makes the subject (participant) clear&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| destroy_participant&lt;br /&gt;
| More descriptive for further use&lt;br /&gt;
|-&lt;br /&gt;
| filter_user_participants&lt;br /&gt;
| participants_for_user&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| filter_assignment_participants&lt;br /&gt;
| participants_for_assignment&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| validated_authorization&lt;br /&gt;
| Suggests return value is validated&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Improve Documentation and Comments===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Proposed Testing Changes===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add more descriptive comments for tests&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that authorizations are updated correctly&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that inputted path parameters are not missing and valid inputs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Tests at Line 222 and Line 231 are redundant, as the only difference in the test is the authorization, which would not affect what happens if a participant is not found&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Implementation (TEMP)==&lt;br /&gt;
&lt;br /&gt;
==Testing Plan (TEMP)==&lt;br /&gt;
&lt;br /&gt;
From the previous implementation, there are 24 tests that are all passing. For more information about the previous testing plan, please refer to the previous implementation's page here: [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2484._Reimplement_participants_controller.rb]&lt;br /&gt;
&lt;br /&gt;
===New/Modified Tests===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (TEMP)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Next Steps (TEMP)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Key concerns identified include the overlap and redundancy within the current system:&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
&lt;br /&gt;
Pull Request (Unimplemented) [] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163869</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163869"/>
		<updated>2025-04-08T05:28:02Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Provide More Clarity in Function Names */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
==Use of Large Language Models (LLMs)==&lt;br /&gt;
&lt;br /&gt;
For this project, we are using ChatGPT as an LLM helper in determining what issues there are within the code.&lt;br /&gt;
&lt;br /&gt;
Below we have organized the following prompts and a summary of the output in a table:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Prompts !! LLM Output &lt;br /&gt;
|-&lt;br /&gt;
| [Code in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;] Are there any ways where we can refactor the code to improve readability, DRYness, and clarity of error handling? || It recognized some of the issues we, as a team, had already identified: &amp;lt;b&amp;gt;Redundant JSON Rendering Code&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;Simplifying the Assignment of Participant Fields&amp;lt;/b&amp;gt;. [IN PROGRESS]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed information on what prompts we used and the output we got, please visit the page here: [https://docs.google.com/document/d/105_U_Coky-edx7n-tFhD2B5RqmVXxEsKPW_qUaf7bQU/edit?usp=sharing].&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Some API functions are not returning the correct HTML status messages (e.g. test on line 136 returns 201 instead of 200)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Documentation and comments can be somewhat vague&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;In-line comments should be more descriptive, explaining what the code does in more details&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Tests are not described via comments, but in name alone; some more descriptive comments that explain the tests in more detail would be ideal&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution (TEMP)==&lt;br /&gt;
&lt;br /&gt;
===Simplifying Redundant JSON Rendering Code===&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Simplifying the Assignment of Participant Fields===&lt;br /&gt;
&lt;br /&gt;
In the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Provide More Clarity in Function Names===&lt;br /&gt;
&lt;br /&gt;
There are some functions that are somewhat unclear/vague in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. For example, the &amp;lt;code&amp;gt;list_user_participants()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Suggested Method Name Improvements ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Old Method Name&lt;br /&gt;
! New Method Name&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| list_user_participants&lt;br /&gt;
| participants_by_user&lt;br /&gt;
| Clearer and more descriptive&lt;br /&gt;
|-&lt;br /&gt;
| list_assignment_participants&lt;br /&gt;
| participants_by_assignment&lt;br /&gt;
| Consistent with the above&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| show_participant&lt;br /&gt;
| Explicit about what is shown&lt;br /&gt;
|-&lt;br /&gt;
| add&lt;br /&gt;
| create_participant_with_authorization&lt;br /&gt;
| Describes both creation and auth setup&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| update_participant_authorization&lt;br /&gt;
| Makes the subject (participant) clear&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| destroy_participant&lt;br /&gt;
| More descriptive for further use&lt;br /&gt;
|-&lt;br /&gt;
| filter_user_participants&lt;br /&gt;
| participants_for_user&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| filter_assignment_participants&lt;br /&gt;
| participants_for_assignment&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| validated_authorization&lt;br /&gt;
| Suggests return value is validated&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Improve Documentation and Comments===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Proposed Testing Changes===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add more descriptive comments for tests&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that authorizations are updated correctly&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that inputted path parameters are not missing and valid inputs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Tests at Line 222 and Line 231 are redundant, as the only difference in the test is the authorization, which would not affect what happens if a participant is not found&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Implementation (TEMP)==&lt;br /&gt;
&lt;br /&gt;
==Testing Plan (TEMP)==&lt;br /&gt;
&lt;br /&gt;
From the previous implementation, there are 24 tests that are all passing. For more information about the previous testing plan, please refer to the previous implementation's page here: [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2484._Reimplement_participants_controller.rb]&lt;br /&gt;
&lt;br /&gt;
===New/Modified Tests===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (TEMP)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Next Steps (TEMP)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Key concerns identified include the overlap and redundancy within the current system:&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
&lt;br /&gt;
Pull Request (Unimplemented) [] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163868</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163868"/>
		<updated>2025-04-08T05:27:46Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Provide More Clarity in Function Names */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
==Use of Large Language Models (LLMs)==&lt;br /&gt;
&lt;br /&gt;
For this project, we are using ChatGPT as an LLM helper in determining what issues there are within the code.&lt;br /&gt;
&lt;br /&gt;
Below we have organized the following prompts and a summary of the output in a table:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Prompts !! LLM Output &lt;br /&gt;
|-&lt;br /&gt;
| [Code in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;] Are there any ways where we can refactor the code to improve readability, DRYness, and clarity of error handling? || It recognized some of the issues we, as a team, had already identified: &amp;lt;b&amp;gt;Redundant JSON Rendering Code&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;Simplifying the Assignment of Participant Fields&amp;lt;/b&amp;gt;. [IN PROGRESS]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed information on what prompts we used and the output we got, please visit the page here: [https://docs.google.com/document/d/105_U_Coky-edx7n-tFhD2B5RqmVXxEsKPW_qUaf7bQU/edit?usp=sharing].&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Some API functions are not returning the correct HTML status messages (e.g. test on line 136 returns 201 instead of 200)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Documentation and comments can be somewhat vague&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;In-line comments should be more descriptive, explaining what the code does in more details&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Tests are not described via comments, but in name alone; some more descriptive comments that explain the tests in more detail would be ideal&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution (TEMP)==&lt;br /&gt;
&lt;br /&gt;
===Simplifying Redundant JSON Rendering Code===&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Simplifying the Assignment of Participant Fields===&lt;br /&gt;
&lt;br /&gt;
In the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Provide More Clarity in Function Names==&lt;br /&gt;
&lt;br /&gt;
There are some functions that are somewhat unclear/vague in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. For example, the &amp;lt;code&amp;gt;list_user_participants()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Suggested Method Name Improvements ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Old Method Name&lt;br /&gt;
! New Method Name&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| list_user_participants&lt;br /&gt;
| participants_by_user&lt;br /&gt;
| Clearer and more descriptive&lt;br /&gt;
|-&lt;br /&gt;
| list_assignment_participants&lt;br /&gt;
| participants_by_assignment&lt;br /&gt;
| Consistent with the above&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| show_participant&lt;br /&gt;
| Explicit about what is shown&lt;br /&gt;
|-&lt;br /&gt;
| add&lt;br /&gt;
| create_participant_with_authorization&lt;br /&gt;
| Describes both creation and auth setup&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| update_participant_authorization&lt;br /&gt;
| Makes the subject (participant) clear&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| destroy_participant&lt;br /&gt;
| More descriptive for further use&lt;br /&gt;
|-&lt;br /&gt;
| filter_user_participants&lt;br /&gt;
| participants_for_user&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| filter_assignment_participants&lt;br /&gt;
| participants_for_assignment&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| validated_authorization&lt;br /&gt;
| Suggests return value is validated&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Improve Documentation and Comments===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Proposed Testing Changes===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add more descriptive comments for tests&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that authorizations are updated correctly&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that inputted path parameters are not missing and valid inputs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Tests at Line 222 and Line 231 are redundant, as the only difference in the test is the authorization, which would not affect what happens if a participant is not found&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Implementation (TEMP)==&lt;br /&gt;
&lt;br /&gt;
==Testing Plan (TEMP)==&lt;br /&gt;
&lt;br /&gt;
From the previous implementation, there are 24 tests that are all passing. For more information about the previous testing plan, please refer to the previous implementation's page here: [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2484._Reimplement_participants_controller.rb]&lt;br /&gt;
&lt;br /&gt;
===New/Modified Tests===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (TEMP)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Next Steps (TEMP)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Key concerns identified include the overlap and redundancy within the current system:&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
&lt;br /&gt;
Pull Request (Unimplemented) [] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163867</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163867"/>
		<updated>2025-04-08T05:27:22Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Provide More Clarity in Function Names */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
==Use of Large Language Models (LLMs)==&lt;br /&gt;
&lt;br /&gt;
For this project, we are using ChatGPT as an LLM helper in determining what issues there are within the code.&lt;br /&gt;
&lt;br /&gt;
Below we have organized the following prompts and a summary of the output in a table:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Prompts !! LLM Output &lt;br /&gt;
|-&lt;br /&gt;
| [Code in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;] Are there any ways where we can refactor the code to improve readability, DRYness, and clarity of error handling? || It recognized some of the issues we, as a team, had already identified: &amp;lt;b&amp;gt;Redundant JSON Rendering Code&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;Simplifying the Assignment of Participant Fields&amp;lt;/b&amp;gt;. [IN PROGRESS]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed information on what prompts we used and the output we got, please visit the page here: [https://docs.google.com/document/d/105_U_Coky-edx7n-tFhD2B5RqmVXxEsKPW_qUaf7bQU/edit?usp=sharing].&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Some API functions are not returning the correct HTML status messages (e.g. test on line 136 returns 201 instead of 200)&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Documentation and comments can be somewhat vague&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;In-line comments should be more descriptive, explaining what the code does in more details&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Tests are not described via comments, but in name alone; some more descriptive comments that explain the tests in more detail would be ideal&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution (TEMP)==&lt;br /&gt;
&lt;br /&gt;
===Simplifying Redundant JSON Rendering Code===&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Simplifying the Assignment of Participant Fields===&lt;br /&gt;
&lt;br /&gt;
In the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Provide More Clarity in Function Names===&lt;br /&gt;
&lt;br /&gt;
There are some functions that are somewhat unclear/vague in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. For example, the &amp;lt;code&amp;gt;list_user_participants()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Suggested Method Name Improvements ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Old Method Name&lt;br /&gt;
! New Method Name&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| list_user_participants&lt;br /&gt;
| participants_by_user&lt;br /&gt;
| Clearer and more descriptive&lt;br /&gt;
|-&lt;br /&gt;
| list_assignment_participants&lt;br /&gt;
| participants_by_assignment&lt;br /&gt;
| Consistent with the above&lt;br /&gt;
|-&lt;br /&gt;
| show&lt;br /&gt;
| show_participant&lt;br /&gt;
| Explicit about what is shown&lt;br /&gt;
|-&lt;br /&gt;
| add&lt;br /&gt;
| create_participant_with_authorization&lt;br /&gt;
| Describes both creation and auth setup&lt;br /&gt;
|-&lt;br /&gt;
| update_authorization&lt;br /&gt;
| update_participant_authorization&lt;br /&gt;
| Makes the subject (participant) clear&lt;br /&gt;
|-&lt;br /&gt;
| destroy&lt;br /&gt;
| destroy_participant&lt;br /&gt;
| More descriptive for further use&lt;br /&gt;
|-&lt;br /&gt;
| filter_user_participants&lt;br /&gt;
| participants_for_user&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| filter_assignment_participants&lt;br /&gt;
| participants_for_assignment&lt;br /&gt;
| Highlights the purpose of the method&lt;br /&gt;
|-&lt;br /&gt;
| validate_authorization&lt;br /&gt;
| validated_authorization&lt;br /&gt;
| Suggests return value is validated&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Improve Documentation and Comments===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Proposed Testing Changes===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add more descriptive comments for tests&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that authorizations are updated correctly&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Add test that checks that inputted path parameters are not missing and valid inputs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Tests at Line 222 and Line 231 are redundant, as the only difference in the test is the authorization, which would not affect what happens if a participant is not found&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Implementation (TEMP)==&lt;br /&gt;
&lt;br /&gt;
==Testing Plan (TEMP)==&lt;br /&gt;
&lt;br /&gt;
From the previous implementation, there are 24 tests that are all passing. For more information about the previous testing plan, please refer to the previous implementation's page here: [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2484._Reimplement_participants_controller.rb]&lt;br /&gt;
&lt;br /&gt;
===New/Modified Tests===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (TEMP)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Next Steps (TEMP)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Key concerns identified include the overlap and redundancy within the current system:&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
&lt;br /&gt;
Pull Request (Unimplemented) [] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163487</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163487"/>
		<updated>2025-04-08T00:24:15Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Existing Issues */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
==Use of Large Language Models (LLMs)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;In-code comments should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution (TEMP)==&lt;br /&gt;
&lt;br /&gt;
===Simplifying Redundant JSON Rendering Code===&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Simplifying the Assignment of Participant Fields===&lt;br /&gt;
&lt;br /&gt;
In the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Provide More Clarity in Function Names===&lt;br /&gt;
&lt;br /&gt;
There are some functions that are somewhat unclear/vague in &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt;. For example, the &amp;lt;code&amp;gt;list_user_participants()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;list_assignment_participants()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Improve Documentation and Comments===&lt;br /&gt;
&lt;br /&gt;
==Implementation (TEMP)==&lt;br /&gt;
&lt;br /&gt;
==Testing Plan (TEMP)==&lt;br /&gt;
&lt;br /&gt;
From the previous implementation, there are 24 tests that are all passing.&lt;br /&gt;
&lt;br /&gt;
====Tests====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (TEMP)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Next Steps (TEMP)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Key concerns identified include the overlap and redundancy within the current system:&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
&lt;br /&gt;
Pull Request (Unimplemented) [] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; participants_controller.rb &amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; participants_helper.rb &amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163479</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163479"/>
		<updated>2025-04-08T00:15:05Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Existing Issues */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
==Use of Large Language Models (LLMs)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;In-code comments should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;make precise for each method&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution (TEMP)==&lt;br /&gt;
&lt;br /&gt;
===Simplifying Redundant JSON Rendering Code===&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Simplifying the Assignment of Participant Fields===&lt;br /&gt;
&lt;br /&gt;
In the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Implementation (TEMP)==&lt;br /&gt;
&lt;br /&gt;
==Testing Plan (TEMP)==&lt;br /&gt;
&lt;br /&gt;
From the previous implementation, there are 24 tests that are all passing.&lt;br /&gt;
&lt;br /&gt;
====Tests====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (TEMP)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Next Steps (TEMP)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Key concerns identified include the overlap and redundancy within the current system:&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
&lt;br /&gt;
Pull Request (Unimplemented) [] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; participants_controller.rb &amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; participants_helper.rb &amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163476</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163476"/>
		<updated>2025-04-08T00:11:32Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Existing Issues */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot; Since this is a refactoring project, we will also be utilizing Large Language Models (LLMs) to aid in development. More information on how we used them can be found in the section below.&lt;br /&gt;
&lt;br /&gt;
==Use of Large Language Models (LLMs)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly, making it somewhat difficult to test&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;In-code comments should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;The method naming should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution (TEMP)==&lt;br /&gt;
&lt;br /&gt;
===Simplifying Redundant JSON Rendering Code===&lt;br /&gt;
&lt;br /&gt;
Many of the functions in the current implementation contain a conditional if-else statement that determines what HTML status code is returned alongside any necessary values that are requested. Due to its simple nature, it might be possible to reduce the amount of space this takes up by implementing a private helper method that would shorten the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  if participants.nil?&lt;br /&gt;
    render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
  else&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Simplifying the Assignment of Participant Fields===&lt;br /&gt;
&lt;br /&gt;
In the &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; both take up a significant amount of space to assign values to database fields and are essentially the same in functionality (in terms of this specific section. We can remove redundancy by creating a method that can remove this redundancy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
  participant.authorization = authorization&lt;br /&gt;
  participant.can_submit = permissions[:can_submit]&lt;br /&gt;
  participant.can_review = permissions[:can_review]&lt;br /&gt;
  participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  participant.can_mentor = permissions[:can_mentor]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Implementation (TEMP)==&lt;br /&gt;
&lt;br /&gt;
==Testing Plan (TEMP)==&lt;br /&gt;
&lt;br /&gt;
From the previous implementation, there are 24 tests that are all passing.&lt;br /&gt;
&lt;br /&gt;
====Tests====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (TEMP)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Next Steps (TEMP)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Key concerns identified include the overlap and redundancy within the current system:&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
&lt;br /&gt;
Pull Request (Unimplemented) [] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; participants_controller.rb &amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; participants_helper.rb &amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163372</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163372"/>
		<updated>2025-04-07T00:12:16Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&lt;br /&gt;
&lt;br /&gt;
==Use of Large Language Models (LLMs)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&amp;lt;b&amp;gt;Objectives:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Apply DRY principles to eliminate redundant code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure adherence to SOLID principles for better maintainability.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use appropriate design patterns to optimize code architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Write clear, informative comments and use meaningful naming conventions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Test the refactored code extensively with RSpec to verify functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Deliverables:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refactored code for participants_controller.rb and helper class.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Comprehensive test suite and coverage report.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Updated and detailed documentation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Video demonstration of the API functionality.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;There are some API functions that are currently not functioning properly:&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;[API functions here]&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;li&amp;gt;In-code comments should be more descriptive&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Eliminate instances of redundant code&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution (OLD/TEMP) ==&lt;br /&gt;
&lt;br /&gt;
==Implementation (TEMP)==&lt;br /&gt;
&lt;br /&gt;
==Testing Plan (TEMP)==&lt;br /&gt;
&lt;br /&gt;
====Tests====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test 'assignment_index' with valid assignment ID - Should list participants&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Next Steps (TEMP)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Key concerns identified include the overlap and redundancy within the current system:&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
&lt;br /&gt;
Pull Request (Unimplemented) [] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; participants_controller.rb &amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; participants_helper.rb &amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163352</id>
		<title>CSC/ECE 517 Spring 2025 - E2531 Refactor participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2531_Refactor_participants_controller.rb&amp;diff=163352"/>
		<updated>2025-04-06T23:05:50Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Relevant Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==About Expertiza==&lt;br /&gt;
Expertiza is an open-source project used to manage and submit assignments for CSC 517: Object-Oriented Design &amp;amp; Development as well as serving as a way for CSC 517 students to be able to apply their skills with the Ruby on Rails framework when contributing to the project. Using the site, students are able to access assignments that are assigned to them by the teaching staff or request topics that are opened to students at the instructor's discretion. Students are also able to submit multiple file types as deliverables (.pdf, links, etc.) in the event that an assignment requires multiple deliverables.&lt;br /&gt;
&lt;br /&gt;
Expertiza's use in the classroom is also a way to familiarize students with the system as they use it throughout the semester before having to contribute to it themselves. This way, students can more accurately understand and infer why and how the codebase operates when they eventually begin work on it.&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
From the project description: &amp;quot;This project aims to refactor the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and its helper class, &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;, in the Expertiza system. The focus will be on improving code structure by implementing DRY and SOLID principles, enhancing readability with meaningful comments and clear naming conventions, and ensuring robustness through comprehensive RSpec testing.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution (OLD/TEMP) ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt; participants_controller.rb &amp;lt;/code&amp;gt; Methods / API Calls===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Method !! Endpoint !! Description &lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|user_index&lt;br /&gt;
|GET &amp;lt;code&amp;gt; /participants/user/:user_id &amp;lt;/code&amp;gt;&lt;br /&gt;
|Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|assignment_index&lt;br /&gt;
|GET &amp;lt;code&amp;gt; /participants/assignment/:assignment_id &amp;lt;/code&amp;gt;&lt;br /&gt;
|Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|show&lt;br /&gt;
|GET &amp;lt;code&amp;gt; /participants/:id &amp;lt;/code&amp;gt;&lt;br /&gt;
|Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|add&lt;br /&gt;
|POST &amp;lt;code&amp;gt; /participants/:authorization &amp;lt;/code&amp;gt;&lt;br /&gt;
|Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|update_authorization&lt;br /&gt;
|PATCH &amp;lt;code&amp;gt; /participants/:id/:authorization &amp;lt;/code&amp;gt;&lt;br /&gt;
|Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|destroy&lt;br /&gt;
|DELETE &amp;lt;code&amp;gt; /participants/:id &amp;lt;/code&amp;gt;&lt;br /&gt;
|Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|participant_params&lt;br /&gt;
| -&lt;br /&gt;
|Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The following methods were removed from &amp;lt;code&amp;gt; participants_controller.rb &amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt; participants_helper.rb &amp;lt;/code&amp;gt; Methods===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Pattern(s)===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===SOLID Principle(s)===&lt;br /&gt;
&lt;br /&gt;
==Implementation (TEMP)==&lt;br /&gt;
===Implement &amp;lt;code&amp;gt; participants_controller.rb &amp;lt;/code&amp;gt; Methods===&lt;br /&gt;
Refer to the [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2484._Reimplement_participants_controller.rb#participants_controller.rb_Methods_/_API_Calls &amp;lt;code&amp;gt; participants_controller.rb &amp;lt;/code&amp;gt; Methods / API Calls] section for a brief overview of its use &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! Old Method Name !! Action !! New Method Name&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed? || Removed || -&lt;br /&gt;
|-&lt;br /&gt;
| controller_locale || Removed || -&lt;br /&gt;
|-&lt;br /&gt;
| list || Renamed and Separated || user_index&lt;br /&gt;
|-&lt;br /&gt;
| - || - || assignment_index&lt;br /&gt;
|-&lt;br /&gt;
| add || No Change || add&lt;br /&gt;
|-&lt;br /&gt;
| update_authorizations || Renamed || update_authorization&lt;br /&gt;
|-&lt;br /&gt;
| destroy || No Change || destroy&lt;br /&gt;
|-&lt;br /&gt;
| inherit || Removed || -&lt;br /&gt;
|-&lt;br /&gt;
| bequeath_all || Removed || -&lt;br /&gt;
|-&lt;br /&gt;
| change_handle || Removed || -&lt;br /&gt;
|-&lt;br /&gt;
| delete || Removed || -&lt;br /&gt;
|-&lt;br /&gt;
| view_copyright_grants || Removed || -&lt;br /&gt;
|-&lt;br /&gt;
| participant_params || No Change || participant_params&lt;br /&gt;
|-&lt;br /&gt;
| get_user_info || Removed || -&lt;br /&gt;
|-&lt;br /&gt;
| get_signup_topics_for_assignment || Removed || -&lt;br /&gt;
|-&lt;br /&gt;
| - || Added || show&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;user_index&amp;lt;/code&amp;gt; Method====&lt;br /&gt;
Description:&lt;br /&gt;
&lt;br /&gt;
This method retrieves a list of participants associated with a specific user. If a valid &amp;lt;code&amp;gt;user_id&amp;lt;/code&amp;gt; is provided in the request, the system searches for the corresponding user and returns the list of participants linked to that user. If no participants are found, or if the user is invalid, an appropriate error response is returned. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;user_id&amp;lt;/code&amp;gt;: The ID of the user whose participants you want to retrieve. If the user does not exist, the method returns without further action. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Behavior:&lt;br /&gt;
&lt;br /&gt;
*The method validates the presence and existence of the &amp;lt;code&amp;gt;user_id&amp;lt;/code&amp;gt;.&lt;br /&gt;
**If the &amp;lt;code&amp;gt;user_id&amp;lt;/code&amp;gt; is invalid, the method then stops execution and does not proceed with participant retrieval.&lt;br /&gt;
**If a valid user is provided, then it will retrieve all participants and filter in the ones of the provided user.&lt;br /&gt;
***The final filtered list of participants is returned as a JSON response containing a confirmation message and a 200 OK status.&lt;br /&gt;
***If the final list would be empty, then it will return a JSON response containing validation errors and a 422 Unprocessable Entity status.&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;pre&amp;gt;  # Return a list of participants for a given user&lt;br /&gt;
  # params - user_id&lt;br /&gt;
  # GET /participants/user/:user_id&lt;br /&gt;
  def user_index&lt;br /&gt;
    user = find_user if params[:user_id].present?&lt;br /&gt;
    return if params[:user_id].present? &amp;amp;&amp;amp; user.nil?&lt;br /&gt;
&lt;br /&gt;
    participants = filter_user_participants(user)&lt;br /&gt;
&lt;br /&gt;
    if participants.nil?&lt;br /&gt;
      render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participants, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assignment_index&amp;lt;/code&amp;gt; Method====&lt;br /&gt;
Description:&lt;br /&gt;
&lt;br /&gt;
This method retrieves a list of participants associated with a specific assignment. If a valid &amp;lt;code&amp;gt;assignment_id&amp;lt;/code&amp;gt; is provided in the request, the system searches for the corresponding assignment and returns the list of participants linked to that assignment. If no participants are found, or if the assignment is invalid, an appropriate error response is returned. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;assignment_id&amp;lt;/code&amp;gt;: The ID of the assignment whose participants you want to retrieve. If the assignment does not exist, the method returns without further action. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Behavior:&lt;br /&gt;
&lt;br /&gt;
*The method validates the presence and existence of the &amp;lt;code&amp;gt;assignment_id&amp;lt;/code&amp;gt;.&lt;br /&gt;
**If the assignment_id is invalid, the method then stops execution and does not proceed with participant retrieval. &lt;br /&gt;
**If a valid assignment is provided, then it will retrieve all participants and filter in the ones of the provided assignment.&lt;br /&gt;
***The final filtered list of participants is returned as a JSON response containing a confirmation message and a 200 OK status.&lt;br /&gt;
***If the final list would be empty, then it will return a JSON response containing validation errors and a 422 Unprocessable Entity status.&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # Return a list of participants for a given assignment&lt;br /&gt;
  # params - assignment_id&lt;br /&gt;
  # GET /participants/assignment/:assignment_id&lt;br /&gt;
  def assignment_index&lt;br /&gt;
    assignment = find_assignment if params[:assignment_id].present?&lt;br /&gt;
    return if params[:assignment_id].present? &amp;amp;&amp;amp; assignment.nil?&lt;br /&gt;
&lt;br /&gt;
    participants = filter_assignment_participants(assignment)&lt;br /&gt;
&lt;br /&gt;
    if participants.nil?&lt;br /&gt;
      render json: participants.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participants, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; Method====&lt;br /&gt;
&lt;br /&gt;
Description:&lt;br /&gt;
&lt;br /&gt;
Assigns the specified authorization to a participant and adds them to a given assignment. It performs the necessary validations to ensure that the user, assignment, and authorization are valid before proceeding. If all validations pass, it associates the participant with the assignment and applies the relevant permissions based on the authorization.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;user_id&amp;lt;/code&amp;gt; (required): The ID of the user to be added as a participant. &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;assignment_id&amp;lt;/code&amp;gt; (required): The ID of the assignment the user will be added to. &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; (required): The authorization ID to define the user's permissions within the assignment.&lt;br /&gt;
&lt;br /&gt;
Behavior:&lt;br /&gt;
&lt;br /&gt;
*Validates and retrieves the user based on the provided &amp;lt;code&amp;gt;user_id&amp;lt;/code&amp;gt;. If the user is not found, the method terminates.&lt;br /&gt;
*Validates and retrieves the assignment based on the provided &amp;lt;code&amp;gt;assignment_id&amp;lt;/code&amp;gt;. If the assignment is not found, the method terminates.&lt;br /&gt;
*Validates and retrieves the authorization based on the provided &amp;lt;code&amp;gt;assignment_id&amp;lt;/code&amp;gt;. If the authorization is not found, the method terminates.&lt;br /&gt;
*Builds a new participant instance linked to the validated user and assignment, with the appropriate permissions obtained from authorization.&lt;br /&gt;
*Attempts to save the participant:&lt;br /&gt;
**If successful: Returns a JSON response containing the created participant and a 201 Created status.&lt;br /&gt;
**If unsuccessful: Returns a JSON response containing validation errors and a 422 Unprocessable Entity status.&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;pre&amp;gt;  # Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
  # POST /participants/:authorization&lt;br /&gt;
  def add&lt;br /&gt;
    user = find_user&lt;br /&gt;
    return unless user&lt;br /&gt;
&lt;br /&gt;
    assignment = find_assignment&lt;br /&gt;
    return unless assignment&lt;br /&gt;
&lt;br /&gt;
    authorization = validate_authorization&lt;br /&gt;
    return unless authorization&lt;br /&gt;
&lt;br /&gt;
    permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
    participant = assignment.add_participant(user)&lt;br /&gt;
    participant.authorization = authorization&lt;br /&gt;
    participant.can_submit = permissions[:can_submit]&lt;br /&gt;
    participant.can_review = permissions[:can_review]&lt;br /&gt;
    participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
    participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
&lt;br /&gt;
    if participant.save&lt;br /&gt;
      render json: participant, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;update_authorization&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
Description:&lt;br /&gt;
&lt;br /&gt;
Updates the authorization and associated permissions for an existing participant.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;participant_id&amp;lt;/code&amp;gt; (required): The ID of the participant whose authorization is being updated. &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; (required): The new authorization ID to assign to the participant.&lt;br /&gt;
&lt;br /&gt;
Behavior:&lt;br /&gt;
*Validates the provided authorization using &amp;lt;code&amp;gt;validate_authorization&amp;lt;/code&amp;gt; after finding the participant. If the authorization is missing, the method halts and returns a 422 Unprocessable Entity status.&lt;br /&gt;
*Upon successful validation of the authorization, the method retrieves the permissions associated with the authorization by calling &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt;.&lt;br /&gt;
*Updates the participant's authorization field with the new authorization. Relevant permissions (can_submit, can_review, can_take_quiz, and can_mentor) are also updated based on the authorization’s values.&lt;br /&gt;
*Attempts to save the updated participant&lt;br /&gt;
**If the participant is successfully updated and saved to the database, a JSON response with the updated participant details and a 201 Created status is returned.&lt;br /&gt;
**If there are validation errors or the update fails, a JSON response with error details and a 422 Unprocessable Entity status is returned.&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;pre&amp;gt;  # Update the specified participant to the specified authorization&lt;br /&gt;
  # PATCH /participants/:id/:authorization&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = find_participant&lt;br /&gt;
    return unless participant&lt;br /&gt;
&lt;br /&gt;
    authorization = validate_authorization&lt;br /&gt;
    return unless authorization&lt;br /&gt;
&lt;br /&gt;
    permissions = retrieve_participant_permissions(authorization)&lt;br /&gt;
&lt;br /&gt;
    participant.authorization = authorization&lt;br /&gt;
    participant.can_submit = permissions[:can_submit]&lt;br /&gt;
    participant.can_review = permissions[:can_review]&lt;br /&gt;
    participant.can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
    participant.can_mentor = permissions[:can_mentor]&lt;br /&gt;
&lt;br /&gt;
    if participant.save&lt;br /&gt;
      render json: participant, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;destroy&amp;lt;/code&amp;gt; Method====&lt;br /&gt;
&lt;br /&gt;
Description:&lt;br /&gt;
&lt;br /&gt;
Deletes a specified participant based on the provided ID.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; (required): The ID of the participant to be deleted.&lt;br /&gt;
&lt;br /&gt;
Behavior:&lt;br /&gt;
&lt;br /&gt;
*Retrieves the participant using the provided &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;.&lt;br /&gt;
*Attempts to delete the participant:&lt;br /&gt;
**If successful: Returns a JSON response containing a confirmation message and a 200 OK status.&lt;br /&gt;
**If unsuccessful: Returns a JSON response containing validation errors and a 422 Unprocessable Entity status.&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;pre&amp;gt;  # Delete a participant&lt;br /&gt;
  # params - id&lt;br /&gt;
  # DELETE /participants/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    participant = Participant.find_by(id: params[:id])&lt;br /&gt;
  &lt;br /&gt;
    if participant.nil?&lt;br /&gt;
      render json: { error: 'Not Found' }, status: :not_found&lt;br /&gt;
    elsif participant.destroy&lt;br /&gt;
      successful_deletion_message = if params[:team_id].nil?&lt;br /&gt;
                                      &amp;quot;Participant #{params[:id]} in Assignment #{params[:assignment_id]} has been deleted successfully!&amp;quot;&lt;br /&gt;
                                    else&lt;br /&gt;
                                      &amp;quot;Participant #{params[:id]} in Team #{params[:team_id]} of Assignment #{params[:assignment_id]} has been deleted successfully!&amp;quot;&lt;br /&gt;
                                    end&lt;br /&gt;
      render json: { message: successful_deletion_message }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;show&amp;lt;/code&amp;gt; Method (TEMP)====&lt;br /&gt;
&lt;br /&gt;
Description:&lt;br /&gt;
&lt;br /&gt;
Retrieves and returns a specific participant based on the provided ID.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; (required): The ID of the participant to be retrieved.&lt;br /&gt;
&lt;br /&gt;
Behavior:&lt;br /&gt;
&lt;br /&gt;
*Fetches the participant from the database using the provided &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;.&lt;br /&gt;
*Attempts to fetch the participant:&lt;br /&gt;
**If successful: Returns a JSON response containing a confirmation message and a 200 OK status.&lt;br /&gt;
**If unsuccessful: Returns a JSON response containing validation errors and a 422 Unprocessable Entity status.&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;pre&amp;gt;  # Return a specified participant&lt;br /&gt;
  # params - id&lt;br /&gt;
  # GET /participants/:id&lt;br /&gt;
  def show&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if participant.nil?&lt;br /&gt;
      render json: participant.errors, status: :unprocessable_entity&lt;br /&gt;
    else&lt;br /&gt;
      render json: participant, status: :created&lt;br /&gt;
    end&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;participant_params&amp;lt;/code&amp;gt; Method====&lt;br /&gt;
&lt;br /&gt;
Description:&lt;br /&gt;
&lt;br /&gt;
Defines the permitted parameters for creating or updating a participant object.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
The method expects a participant object within the request parameters. It permits the following attributes:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;user_id&amp;lt;/code&amp;gt; (required): The ID of the user associated with the participant.&lt;br /&gt;
*&amp;lt;code&amp;gt;assignment_id&amp;lt;/code&amp;gt; (required): The ID of the assignment linked to the participant.&lt;br /&gt;
*&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; (optional): A string indicating the &amp;quot;Role&amp;quot; of the user, that being one of the following: reader, reviewer, submitter, or mentor.&lt;br /&gt;
*&amp;lt;code&amp;gt;can_submit&amp;lt;/code&amp;gt; (optional): A boolean indicating whether the participant has submit permissions granted.&lt;br /&gt;
*&amp;lt;code&amp;gt;can_review&amp;lt;/code&amp;gt; (optional): A boolean indicating whether the participant has review permissions granted.&lt;br /&gt;
*&amp;lt;code&amp;gt;can_take_quiz&amp;lt;/code&amp;gt; (optional): A boolean indicating whether the participant has take_quiz permissions granted.&lt;br /&gt;
*&amp;lt;code&amp;gt;can_mentor&amp;lt;/code&amp;gt; (optional): A boolean indicating whether the participant has mentor permissions granted.&lt;br /&gt;
*&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; (optional): A string containing the participant's display name.&lt;br /&gt;
*&amp;lt;code&amp;gt;team_id&amp;lt;/code&amp;gt; (optional): The ID of the team the participant belongs to.&lt;br /&gt;
*&amp;lt;code&amp;gt;join_team_request_id&amp;lt;/code&amp;gt; (optional): The ID of any pending team join request related to the participant.&lt;br /&gt;
*&amp;lt;code&amp;gt;permission_granted&amp;lt;/code&amp;gt; (optional): A boolean indicating whether the participant has specific permissions granted.&lt;br /&gt;
*&amp;lt;code&amp;gt;topic&amp;lt;/code&amp;gt; (optional): The topic assigned to the participant (could be a string or other data type depending on the application context).&lt;br /&gt;
*&amp;lt;code&amp;gt;current_stage&amp;lt;/code&amp;gt; (optional): The current progress stage of the participant.&lt;br /&gt;
*&amp;lt;code&amp;gt;stage_deadline&amp;lt;/code&amp;gt; (optional): The deadline for the current stage.&lt;br /&gt;
&lt;br /&gt;
Behavior:&lt;br /&gt;
&lt;br /&gt;
*Ensures that only allowed parameters are passed when creating a participant object.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;filter_user_participants&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
Description:&lt;br /&gt;
&lt;br /&gt;
Retrieves and filters participants based on the provided user.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;user&amp;lt;/code&amp;gt; (required): An instance of the user model. If provided, the method filters participants associated with this user.&lt;br /&gt;
&lt;br /&gt;
Behavior:&lt;br /&gt;
&lt;br /&gt;
*Fetches all participants from the database.&lt;br /&gt;
*The method filters participants where the &amp;lt;code&amp;gt;user_id&amp;lt;/code&amp;gt; matches the given user's ID.&lt;br /&gt;
*The final list of participants is then ordered by their id in ascending order.&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;pre&amp;gt;  # Filters participants based on the provided user&lt;br /&gt;
  # Returns participants ordered by their IDs&lt;br /&gt;
  def filter_user_participants(user)&lt;br /&gt;
    participants = Participant.all&lt;br /&gt;
    participants = participants.where(user_id: user.id) if user&lt;br /&gt;
    participants.order(:id)&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;filter_assignment_participants&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
Description:&lt;br /&gt;
&lt;br /&gt;
Retrieves and filters participants based on the provided assignment.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;assignment&amp;lt;/code&amp;gt; (required): An instance of the assignment model. If provided, the method filters participants associated with this assignment.&lt;br /&gt;
&lt;br /&gt;
Behavior:&lt;br /&gt;
&lt;br /&gt;
*Fetches all participants from the database.&lt;br /&gt;
*The method filters participants where the assignment_id matches the given assignment's ID.&lt;br /&gt;
*The final list of participants is then ordered by their id in ascending order.&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;pre&amp;gt;  def filter_assignment_participants(assignment)&lt;br /&gt;
    participants = Participant.all&lt;br /&gt;
    participants = participants.where(assignment_id: assignment.id) if assignment&lt;br /&gt;
    participants.order(:id)&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;find_user&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
&lt;br /&gt;
Description:&lt;br /&gt;
Retrieves a User object based on the user_id provided. If the user is not found, it returns an error response and halts further execution.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;user_id&amp;lt;/code&amp;gt; (optional): The ID of the user to be retrieved. Extracted from the permitted parameters.&lt;br /&gt;
&lt;br /&gt;
Behavior:&lt;br /&gt;
&lt;br /&gt;
*Attempts to find the user in the database using the provided &amp;lt;code&amp;gt;user_id&amp;lt;/code&amp;gt;.&lt;br /&gt;
**If the user is not found (nil), it renders a JSON response with an error message and 404 Not Found status.&lt;br /&gt;
**If the user exists, it returns the user object with 200 OK status.&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;pre&amp;gt;  def find_user&lt;br /&gt;
    user_id = params[:user_id]&lt;br /&gt;
    user = User.find_by(id: user_id)&lt;br /&gt;
    render json: { error: 'User not found' }, status: :not_found unless user&lt;br /&gt;
    user&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;find_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
&lt;br /&gt;
Description:&lt;br /&gt;
&lt;br /&gt;
Retrieves an assignment object based on the &amp;lt;code&amp;gt;assignment_id&amp;lt;/code&amp;gt; provided. If the assignment is not found, it returns an error response and halts further execution.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;assignment_id&amp;lt;/code&amp;gt; (optional): The ID of the assignment to be retrieved. Extracted from the permitted parameters.&lt;br /&gt;
&lt;br /&gt;
Behavior:&lt;br /&gt;
&lt;br /&gt;
*Attempts to find the assignment in the database using the provided &amp;lt;code&amp;gt;assignment_id&amp;lt;/code&amp;gt;.&lt;br /&gt;
**If the assignment is not found (nil), it renders a JSON response with an error message and 404 Not Found status.&lt;br /&gt;
**If the assignment exists, it returns the assignment object with 200 OK status.&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;pre&amp;gt;  def find_assignment&lt;br /&gt;
    assignment_id = params[:assignment_id]&lt;br /&gt;
    assignment = Assignment.find_by(id: assignment_id)&lt;br /&gt;
    render json: { error: 'Assignment not found' }, status: :not_found unless assignment&lt;br /&gt;
    assignment&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;find_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
&lt;br /&gt;
Description:&lt;br /&gt;
&lt;br /&gt;
Retrieves a participant object based on the &amp;lt;code&amp;gt;participant_id&amp;lt;/code&amp;gt; provided. If the participant is not found, it returns an error response and halts further execution.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;participant_id&amp;lt;/code&amp;gt; (optional): The ID of the participant to be retrieved. Extracted from the permitted parameters.&lt;br /&gt;
&lt;br /&gt;
Behavior:&lt;br /&gt;
&lt;br /&gt;
*Attempts to find the participant in the database using the provided &amp;lt;code&amp;gt;participant_id&amp;lt;/code&amp;gt;.&lt;br /&gt;
**If the participant is not found (nil), it renders a JSON response with an error message and 404 Not Found status.&lt;br /&gt;
**If the participant exists, it returns the participant object with 200 OK status.&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;pre&amp;gt;  def find_participant&lt;br /&gt;
    participant_id = params[:id]&lt;br /&gt;
    participant = Participant.find_by(id: participant_id)&lt;br /&gt;
    render json: { error: 'Participant not found' }, status: :not_found unless participant&lt;br /&gt;
    participant&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;validate_authorization&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
Description:&lt;br /&gt;
*Validates the authorization parameter provided in the request. Ensures that the authorization value is one of the accepted roles: reader, reviewer, submitter, or mentor.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; (required): A string representing the participant’s authorization role. This value must be one of the following: reader, reviewer, submitter, or mentor.&lt;br /&gt;
&lt;br /&gt;
Behavior:&lt;br /&gt;
*If the authorization parameter is present, it is converted to lowercase to ensure case-insensitive comparison.&lt;br /&gt;
*If the authorization parameter is not provided, the method renders a 422 Unprocessable Entity response with an error message indicating that a participant must have an authorization.&lt;br /&gt;
*If the authorization value is provided but does not match one of the valid roles (reader, reviewer, submitter, or mentor), the method renders a 422 Unprocessable Entity response with an error message listing the valid options.&lt;br /&gt;
*If the authorization value is valid, the method returns the authorization string.&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;pre&amp;gt;  def validate_authorization&lt;br /&gt;
    valid_authorizations = %w[reader reviewer submitter mentor]&lt;br /&gt;
    authorization = params[:authorization]&lt;br /&gt;
    authorization = authorization.downcase if authorization.present?&lt;br /&gt;
&lt;br /&gt;
    unless authorization&lt;br /&gt;
      render json: { error: 'authorization is required' }, status: :unprocessable_entity&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    unless valid_authorizations.include?(authorization)&lt;br /&gt;
      render json: { error: 'authorization not valid. Valid authorizations are: Reader, Reviewer, Submitter, Mentor' },&lt;br /&gt;
             status: :unprocessable_entity&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    authorization&lt;br /&gt;
  end&lt;br /&gt;
end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Import from &amp;lt;code&amp;gt; participants_helper.rb &amp;lt;/code&amp;gt;===&lt;br /&gt;
Refer to the [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2484._Reimplement_participants_controller.rb#participants_helper.rb_Methods &amp;lt;code&amp;gt; participants_helper.rb &amp;lt;/code&amp;gt; Methods] section for all design-related inquiries &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! Old Method Name !! Action !! New Method Name&lt;br /&gt;
|-&lt;br /&gt;
| upload_users || Removed || -&lt;br /&gt;
|-&lt;br /&gt;
| define_attributes || Removed || -&lt;br /&gt;
|-&lt;br /&gt;
| define_user || Removed || -&lt;br /&gt;
|-&lt;br /&gt;
| create_new_user || Removed || -&lt;br /&gt;
|-&lt;br /&gt;
| add_user_to_assignment || Removed || -&lt;br /&gt;
|-&lt;br /&gt;
| add_user_to_course || Removed || -&lt;br /&gt;
|-&lt;br /&gt;
| get_config || Removed || -&lt;br /&gt;
|-&lt;br /&gt;
| store_item || Removed || -&lt;br /&gt;
|-&lt;br /&gt;
| participant_permissions || Renamed || retrieve_participant_permissions&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; Method====&lt;br /&gt;
&lt;br /&gt;
Description:&lt;br /&gt;
*Retrieves the permissions associated with a given authorization role. The permissions determine the actions a participant can perform (e.g., submitting, reviewing, taking quizzes, or mentoring). The method merges default permissions with role-specific overrides and returns the final set of permissions for the specified authorization.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; (required): A string representing the participant's authorization role. This value should be one of the following: reader, reviewer, submitter, or mentor.&lt;br /&gt;
Behavior:&lt;br /&gt;
*The method defines a set of default permissions that are assigned to all participants unless overridden by their specific authorization role. The default permissions allow submitting, reviewing, and taking quizzes, while disallowing mentoring.&lt;br /&gt;
*A permissions_map is used to define role-specific overrides for the default permissions:&lt;br /&gt;
**reader: Cannot submit, but can review and take quizzes.&lt;br /&gt;
**reviewer: Cannot submit or take quizzes, but can review.&lt;br /&gt;
**submitter: Cannot review or take quizzes, but can submit.&lt;br /&gt;
**mentor: Can mentor, and has the same permissions as a reader for other actions.&lt;br /&gt;
*The method merges the default permissions with the overrides for the specified authorization. The final set of permissions is returned.&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;pre&amp;gt;  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===API Creation===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Testing with rswag===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Swagger UI Video Documentation===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Testing Plan==&lt;br /&gt;
'''rswag'''&amp;lt;br/&amp;gt;&lt;br /&gt;
We will use rswag to test and document our project’s API endpoints. Rswag integrates RSpec testing with Swagger, allowing us to define test cases in RSpec to validate functionality while automatically generating interactive Swagger documentation. This documentation, accessible through Swagger UI, provides developers and stakeholders with a user-friendly way to explore and interact with our API endpoints.&lt;br /&gt;
&lt;br /&gt;
====Tests====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:40px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Test ID !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (TEMP)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Next Steps==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Key concerns identified include the overlap and redundancy within the current system:&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
'''Mentor''' &lt;br /&gt;
&lt;br /&gt;
*Aniruddha Rajnekar &amp;lt;aarajnek@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Students'''&lt;br /&gt;
&lt;br /&gt;
*Akhil Adusumilli &amp;lt;aadusum@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Vansh Dodiya &amp;lt;vkdodiya@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Brian Huynh &amp;lt;bhhuynh@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
&lt;br /&gt;
Pull Request (Unimplemented) [] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Repository [https://github.com/Vansh17/refactoring-participants-controller.git] &amp;lt;br/&amp;gt;&lt;br /&gt;
GitHub Project Board [https://github.com/users/Vansh17/projects/2] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; participants_controller.rb &amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/controllers/participants_controller.rb] &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; participants_helper.rb &amp;lt;/code&amp;gt; in Old Expertiza [https://github.com/expertiza/expertiza/blob/main/app/helpers/participants_helper.rb]&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162854</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162854"/>
		<updated>2025-03-26T02:59:44Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Resources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== SOLID Principles in participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The reimplementation of &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; follows several key SOLID design principles, promoting better structure, maintainability, and testability of the code.&lt;br /&gt;
&lt;br /&gt;
===  Single Responsibility Principle (SRP) ===&lt;br /&gt;
*A class should have only one reason to change.*&lt;br /&gt;
&lt;br /&gt;
The controller now only manages routing and API logic. Role-based permission logic is abstracted into a helper method (or strategy), and user creation is encapsulated using strong params.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
* &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; method handles only participant creation.&lt;br /&gt;
* &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; cleanly maps roles to permission flags.&lt;br /&gt;
* Deprecated methods like &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; were removed to reduce clutter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Open/Closed Principle (OCP) ===&lt;br /&gt;
*Software should be open for extension, but closed for modification.*&lt;br /&gt;
&lt;br /&gt;
The controller supports new roles or permission logic without modifying existing methods. By using &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; or a Strategy Pattern, the controller can support additional behaviors without structural changes.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* You can add new roles (e.g., Observer, Facilitator) by extending the permission logic externally.&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== API Testing with RSpec and Swagger ==&lt;br /&gt;
&lt;br /&gt;
As part of ensuring the stability and correctness of the newly reimplemented ParticipantsController, comprehensive API tests were added using RSpec and rswag (Swagger integration). These tests validate both the happy path and edge cases for participant-related endpoints.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The tests are defined in the following file:&lt;br /&gt;
spec/requests/api/v1/participants_spec.rb&lt;br /&gt;
&lt;br /&gt;
The structure includes the following tested endpoints:&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/user/:user_id ===&lt;br /&gt;
&lt;br /&gt;
Description: Returns all participants associated with a given user.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns list of participants&lt;br /&gt;
* 404 Not Found – User ID does not exist&lt;br /&gt;
* 401 Unauthorized – Invalid or missing token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response is an array of participant objects.&lt;br /&gt;
* Each object contains correct user_id and assignment_id.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/assignment/:assignment_id ===&lt;br /&gt;
&lt;br /&gt;
Description: Returns all participants associated with a specific assignment.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns matching participants&lt;br /&gt;
* 404 Not Found – Assignment ID does not exist&lt;br /&gt;
* 401 Unauthorized – Token is invalid or missing&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response contains participants with matching assignment_id.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/:id ===&lt;br /&gt;
&lt;br /&gt;
Description: Retrieves a single participant by ID.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns the correct participant&lt;br /&gt;
* 404 Not Found – Invalid participant ID&lt;br /&gt;
* 401 Unauthorized – No or invalid token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* JSON contains user_id and assignment_id matching test data.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: DELETE /api/v1/participants/:id ===&lt;br /&gt;
&lt;br /&gt;
Description: Deletes a participant by ID.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 204 No Content – Participant deleted successfully&lt;br /&gt;
* 404 Not Found – Deleting a non-existent participant&lt;br /&gt;
* 401 Unauthorized – Missing or invalid auth token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response body is empty on successful deletion.&lt;br /&gt;
&lt;br /&gt;
=== Authentication ===&lt;br /&gt;
&lt;br /&gt;
Before each test, an admin login is performed, and a valid JWT token is captured and passed in the Authorization header for secure access.&lt;br /&gt;
before(:all) do&lt;br /&gt;
  post '/login', params: { user_name: 'admin2@example.com', password: 'password123' }&lt;br /&gt;
  @token = JSON.parse(response.body)['token']&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The token is used like so:&lt;br /&gt;
&lt;br /&gt;
let(:valid_headers) { { 'Authorization' =&amp;gt; &amp;quot;Bearer #{@token}&amp;quot; } }&lt;br /&gt;
&lt;br /&gt;
=== Error Handling Covered ===&lt;br /&gt;
&lt;br /&gt;
Each endpoint is tested for:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Valid request returns expected data.&lt;br /&gt;
* 404 Not Found – Invalid user_id, assignment_id, or participant_id.&lt;br /&gt;
* 401 Unauthorized – Missing or invalid JWT token.&lt;br /&gt;
&lt;br /&gt;
=== Benefits ===&lt;br /&gt;
&lt;br /&gt;
* Confidence in refactoring: Ensures controller changes don’t break expected behavior.&lt;br /&gt;
* Live API Docs: Swagger UI automatically reflects documented test cases.&lt;br /&gt;
* Security: Token-based auth is enforced and tested for all protected endpoints.&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://github.com/brianhhuynh38/expertiza-e2511/tree/main Github Repository]&lt;br /&gt;
* [https://github.com/users/brianhhuynh38/projects/2 Github Project Board]&lt;br /&gt;
* [https://youtu.be/rwdhideeA_k Video Link]&lt;br /&gt;
* [https://github.com/expertiza/reimplementation-back-end/pull/181 Github Pull Request]&lt;br /&gt;
* [http://152.7.177.193:3002/api-docs/index.html VCL Hosting Swagger]&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya@ncsu.edu)&lt;br /&gt;
* Brian Huynh (bhhuynh@ncsu.edu)&lt;br /&gt;
* Akhil Adusumilli (aadusum@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162795</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162795"/>
		<updated>2025-03-25T03:56:26Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Resources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== SOLID Principles in participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The reimplementation of &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; follows several key SOLID design principles, promoting better structure, maintainability, and testability of the code.&lt;br /&gt;
&lt;br /&gt;
===  Single Responsibility Principle (SRP) ===&lt;br /&gt;
*A class should have only one reason to change.*&lt;br /&gt;
&lt;br /&gt;
The controller now only manages routing and API logic. Role-based permission logic is abstracted into a helper method (or strategy), and user creation is encapsulated using strong params.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
* &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; method handles only participant creation.&lt;br /&gt;
* &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; cleanly maps roles to permission flags.&lt;br /&gt;
* Deprecated methods like &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; were removed to reduce clutter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Open/Closed Principle (OCP) ===&lt;br /&gt;
*Software should be open for extension, but closed for modification.*&lt;br /&gt;
&lt;br /&gt;
The controller supports new roles or permission logic without modifying existing methods. By using &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; or a Strategy Pattern, the controller can support additional behaviors without structural changes.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* You can add new roles (e.g., Observer, Facilitator) by extending the permission logic externally.&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== API Testing with RSpec and Swagger ==&lt;br /&gt;
&lt;br /&gt;
As part of ensuring the stability and correctness of the newly reimplemented ParticipantsController, comprehensive API tests were added using RSpec and rswag (Swagger integration). These tests validate both the happy path and edge cases for participant-related endpoints.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The tests are defined in the following file:&lt;br /&gt;
spec/requests/api/v1/participants_spec.rb&lt;br /&gt;
&lt;br /&gt;
The structure includes the following tested endpoints:&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/user/:user_id ===&lt;br /&gt;
&lt;br /&gt;
Description: Returns all participants associated with a given user.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns list of participants&lt;br /&gt;
* 404 Not Found – User ID does not exist&lt;br /&gt;
* 401 Unauthorized – Invalid or missing token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response is an array of participant objects.&lt;br /&gt;
* Each object contains correct user_id and assignment_id.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/assignment/:assignment_id ===&lt;br /&gt;
&lt;br /&gt;
Description: Returns all participants associated with a specific assignment.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns matching participants&lt;br /&gt;
* 404 Not Found – Assignment ID does not exist&lt;br /&gt;
* 401 Unauthorized – Token is invalid or missing&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response contains participants with matching assignment_id.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/:id ===&lt;br /&gt;
&lt;br /&gt;
Description: Retrieves a single participant by ID.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns the correct participant&lt;br /&gt;
* 404 Not Found – Invalid participant ID&lt;br /&gt;
* 401 Unauthorized – No or invalid token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* JSON contains user_id and assignment_id matching test data.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: DELETE /api/v1/participants/:id ===&lt;br /&gt;
&lt;br /&gt;
Description: Deletes a participant by ID.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 204 No Content – Participant deleted successfully&lt;br /&gt;
* 404 Not Found – Deleting a non-existent participant&lt;br /&gt;
* 401 Unauthorized – Missing or invalid auth token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response body is empty on successful deletion.&lt;br /&gt;
&lt;br /&gt;
=== Authentication ===&lt;br /&gt;
&lt;br /&gt;
Before each test, an admin login is performed, and a valid JWT token is captured and passed in the Authorization header for secure access.&lt;br /&gt;
before(:all) do&lt;br /&gt;
  post '/login', params: { user_name: 'admin2@example.com', password: 'password123' }&lt;br /&gt;
  @token = JSON.parse(response.body)['token']&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The token is used like so:&lt;br /&gt;
&lt;br /&gt;
let(:valid_headers) { { 'Authorization' =&amp;gt; &amp;quot;Bearer #{@token}&amp;quot; } }&lt;br /&gt;
&lt;br /&gt;
=== Error Handling Covered ===&lt;br /&gt;
&lt;br /&gt;
Each endpoint is tested for:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Valid request returns expected data.&lt;br /&gt;
* 404 Not Found – Invalid user_id, assignment_id, or participant_id.&lt;br /&gt;
* 401 Unauthorized – Missing or invalid JWT token.&lt;br /&gt;
&lt;br /&gt;
=== Benefits ===&lt;br /&gt;
&lt;br /&gt;
* Confidence in refactoring: Ensures controller changes don’t break expected behavior.&lt;br /&gt;
* Live API Docs: Swagger UI automatically reflects documented test cases.&lt;br /&gt;
* Security: Token-based auth is enforced and tested for all protected endpoints.&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://github.com/brianhhuynh38/expertiza-e2511/tree/main Github Repository]&lt;br /&gt;
* [https://github.com/users/brianhhuynh38/projects/2 Github Project Board]&lt;br /&gt;
* [https://youtu.be/rwdhideeA_k Video Link]&lt;br /&gt;
* [https://github.com/expertiza/reimplementation-back-end/pull/181 Github Pull Request]&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya@ncsu.edu)&lt;br /&gt;
* Brian Huynh (bhhuynh@ncsu.edu)&lt;br /&gt;
* Akhil Adusumilli (aadusum@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162774</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162774"/>
		<updated>2025-03-25T03:31:05Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Resources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== SOLID Principles in participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The reimplementation of &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; follows several key SOLID design principles, promoting better structure, maintainability, and testability of the code.&lt;br /&gt;
&lt;br /&gt;
===  Single Responsibility Principle (SRP) ===&lt;br /&gt;
*A class should have only one reason to change.*&lt;br /&gt;
&lt;br /&gt;
The controller now only manages routing and API logic. Role-based permission logic is abstracted into a helper method (or strategy), and user creation is encapsulated using strong params.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
* &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; method handles only participant creation.&lt;br /&gt;
* &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; cleanly maps roles to permission flags.&lt;br /&gt;
* Deprecated methods like &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; were removed to reduce clutter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Open/Closed Principle (OCP) ===&lt;br /&gt;
*Software should be open for extension, but closed for modification.*&lt;br /&gt;
&lt;br /&gt;
The controller supports new roles or permission logic without modifying existing methods. By using &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; or a Strategy Pattern, the controller can support additional behaviors without structural changes.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* You can add new roles (e.g., Observer, Facilitator) by extending the permission logic externally.&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== API Testing with RSpec and Swagger ==&lt;br /&gt;
&lt;br /&gt;
As part of ensuring the stability and correctness of the newly reimplemented ParticipantsController, comprehensive API tests were added using RSpec and rswag (Swagger integration). These tests validate both the happy path and edge cases for participant-related endpoints.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The tests are defined in the following file:&lt;br /&gt;
spec/requests/api/v1/participants_spec.rb&lt;br /&gt;
&lt;br /&gt;
The structure includes the following tested endpoints:&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/user/:user_id ===&lt;br /&gt;
&lt;br /&gt;
Description: Returns all participants associated with a given user.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns list of participants&lt;br /&gt;
* 404 Not Found – User ID does not exist&lt;br /&gt;
* 401 Unauthorized – Invalid or missing token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response is an array of participant objects.&lt;br /&gt;
* Each object contains correct user_id and assignment_id.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/assignment/:assignment_id ===&lt;br /&gt;
&lt;br /&gt;
Description: Returns all participants associated with a specific assignment.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns matching participants&lt;br /&gt;
* 404 Not Found – Assignment ID does not exist&lt;br /&gt;
* 401 Unauthorized – Token is invalid or missing&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response contains participants with matching assignment_id.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/:id ===&lt;br /&gt;
&lt;br /&gt;
Description: Retrieves a single participant by ID.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns the correct participant&lt;br /&gt;
* 404 Not Found – Invalid participant ID&lt;br /&gt;
* 401 Unauthorized – No or invalid token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* JSON contains user_id and assignment_id matching test data.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: DELETE /api/v1/participants/:id ===&lt;br /&gt;
&lt;br /&gt;
Description: Deletes a participant by ID.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 204 No Content – Participant deleted successfully&lt;br /&gt;
* 404 Not Found – Deleting a non-existent participant&lt;br /&gt;
* 401 Unauthorized – Missing or invalid auth token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response body is empty on successful deletion.&lt;br /&gt;
&lt;br /&gt;
=== Authentication ===&lt;br /&gt;
&lt;br /&gt;
Before each test, an admin login is performed, and a valid JWT token is captured and passed in the Authorization header for secure access.&lt;br /&gt;
before(:all) do&lt;br /&gt;
  post '/login', params: { user_name: 'admin2@example.com', password: 'password123' }&lt;br /&gt;
  @token = JSON.parse(response.body)['token']&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The token is used like so:&lt;br /&gt;
&lt;br /&gt;
let(:valid_headers) { { 'Authorization' =&amp;gt; &amp;quot;Bearer #{@token}&amp;quot; } }&lt;br /&gt;
&lt;br /&gt;
=== Error Handling Covered ===&lt;br /&gt;
&lt;br /&gt;
Each endpoint is tested for:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Valid request returns expected data.&lt;br /&gt;
* 404 Not Found – Invalid user_id, assignment_id, or participant_id.&lt;br /&gt;
* 401 Unauthorized – Missing or invalid JWT token.&lt;br /&gt;
&lt;br /&gt;
=== Benefits ===&lt;br /&gt;
&lt;br /&gt;
* Confidence in refactoring: Ensures controller changes don’t break expected behavior.&lt;br /&gt;
* Live API Docs: Swagger UI automatically reflects documented test cases.&lt;br /&gt;
* Security: Token-based auth is enforced and tested for all protected endpoints.&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://github.com/brianhhuynh38/expertiza-e2511/tree/main Github Repository]&lt;br /&gt;
* [https://github.com/users/brianhhuynh38/projects/2 Github Project Board]&lt;br /&gt;
* [https://youtu.be/rwdhideeA_k Video Link]&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya@ncsu.edu)&lt;br /&gt;
* Brian Huynh (bhhuynh@ncsu.edu)&lt;br /&gt;
* Akhil Adusumilli (aadusum@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162647</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162647"/>
		<updated>2025-03-25T02:01:57Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Resources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== SOLID Principles in participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The reimplementation of &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; follows several key SOLID design principles, promoting better structure, maintainability, and testability of the code.&lt;br /&gt;
&lt;br /&gt;
===  Single Responsibility Principle (SRP) ===&lt;br /&gt;
*A class should have only one reason to change.*&lt;br /&gt;
&lt;br /&gt;
The controller now only manages routing and API logic. Role-based permission logic is abstracted into a helper method (or strategy), and user creation is encapsulated using strong params.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
* &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; method handles only participant creation.&lt;br /&gt;
* &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; cleanly maps roles to permission flags.&lt;br /&gt;
* Deprecated methods like &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; were removed to reduce clutter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Open/Closed Principle (OCP) ===&lt;br /&gt;
*Software should be open for extension, but closed for modification.*&lt;br /&gt;
&lt;br /&gt;
The controller supports new roles or permission logic without modifying existing methods. By using &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; or a Strategy Pattern, the controller can support additional behaviors without structural changes.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* You can add new roles (e.g., Observer, Facilitator) by extending the permission logic externally.&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== API Testing with RSpec and Swagger ==&lt;br /&gt;
&lt;br /&gt;
As part of ensuring the stability and correctness of the newly reimplemented ParticipantsController, comprehensive API tests were added using RSpec and rswag (Swagger integration). These tests validate both the happy path and edge cases for participant-related endpoints.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The tests are defined in the following file:&lt;br /&gt;
spec/requests/api/v1/participants_spec.rb&lt;br /&gt;
&lt;br /&gt;
The structure includes the following tested endpoints:&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/user/:user_id ===&lt;br /&gt;
&lt;br /&gt;
Description: Returns all participants associated with a given user.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns list of participants&lt;br /&gt;
* 404 Not Found – User ID does not exist&lt;br /&gt;
* 401 Unauthorized – Invalid or missing token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response is an array of participant objects.&lt;br /&gt;
* Each object contains correct user_id and assignment_id.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/assignment/:assignment_id ===&lt;br /&gt;
&lt;br /&gt;
Description: Returns all participants associated with a specific assignment.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns matching participants&lt;br /&gt;
* 404 Not Found – Assignment ID does not exist&lt;br /&gt;
* 401 Unauthorized – Token is invalid or missing&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response contains participants with matching assignment_id.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/:id ===&lt;br /&gt;
&lt;br /&gt;
Description: Retrieves a single participant by ID.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns the correct participant&lt;br /&gt;
* 404 Not Found – Invalid participant ID&lt;br /&gt;
* 401 Unauthorized – No or invalid token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* JSON contains user_id and assignment_id matching test data.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: DELETE /api/v1/participants/:id ===&lt;br /&gt;
&lt;br /&gt;
Description: Deletes a participant by ID.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 204 No Content – Participant deleted successfully&lt;br /&gt;
* 404 Not Found – Deleting a non-existent participant&lt;br /&gt;
* 401 Unauthorized – Missing or invalid auth token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response body is empty on successful deletion.&lt;br /&gt;
&lt;br /&gt;
=== Authentication ===&lt;br /&gt;
&lt;br /&gt;
Before each test, an admin login is performed, and a valid JWT token is captured and passed in the Authorization header for secure access.&lt;br /&gt;
before(:all) do&lt;br /&gt;
  post '/login', params: { user_name: 'admin2@example.com', password: 'password123' }&lt;br /&gt;
  @token = JSON.parse(response.body)['token']&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The token is used like so:&lt;br /&gt;
&lt;br /&gt;
let(:valid_headers) { { 'Authorization' =&amp;gt; &amp;quot;Bearer #{@token}&amp;quot; } }&lt;br /&gt;
&lt;br /&gt;
=== Error Handling Covered ===&lt;br /&gt;
&lt;br /&gt;
Each endpoint is tested for:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Valid request returns expected data.&lt;br /&gt;
* 404 Not Found – Invalid user_id, assignment_id, or participant_id.&lt;br /&gt;
* 401 Unauthorized – Missing or invalid JWT token.&lt;br /&gt;
&lt;br /&gt;
=== Benefits ===&lt;br /&gt;
&lt;br /&gt;
* Confidence in refactoring: Ensures controller changes don’t break expected behavior.&lt;br /&gt;
* Live API Docs: Swagger UI automatically reflects documented test cases.&lt;br /&gt;
* Security: Token-based auth is enforced and tested for all protected endpoints.&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://github.com/brianhhuynh38/expertiza-e2511/tree/main Github Repository]&lt;br /&gt;
* [https://github.com/users/brianhhuynh38/projects/2 Github Project Board]&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya@ncsu.edu)&lt;br /&gt;
* Brian Huynh (bhhuynh@ncsu.edu)&lt;br /&gt;
* Akhil Adusumilli (aadusum@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162645</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162645"/>
		<updated>2025-03-25T01:58:25Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Resources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== SOLID Principles in participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The reimplementation of &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; follows several key SOLID design principles, promoting better structure, maintainability, and testability of the code.&lt;br /&gt;
&lt;br /&gt;
===  Single Responsibility Principle (SRP) ===&lt;br /&gt;
*A class should have only one reason to change.*&lt;br /&gt;
&lt;br /&gt;
The controller now only manages routing and API logic. Role-based permission logic is abstracted into a helper method (or strategy), and user creation is encapsulated using strong params.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
* &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; method handles only participant creation.&lt;br /&gt;
* &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; cleanly maps roles to permission flags.&lt;br /&gt;
* Deprecated methods like &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; were removed to reduce clutter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Open/Closed Principle (OCP) ===&lt;br /&gt;
*Software should be open for extension, but closed for modification.*&lt;br /&gt;
&lt;br /&gt;
The controller supports new roles or permission logic without modifying existing methods. By using &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; or a Strategy Pattern, the controller can support additional behaviors without structural changes.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* You can add new roles (e.g., Observer, Facilitator) by extending the permission logic externally.&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== API Testing with RSpec and Swagger ==&lt;br /&gt;
&lt;br /&gt;
As part of ensuring the stability and correctness of the newly reimplemented ParticipantsController, comprehensive API tests were added using RSpec and rswag (Swagger integration). These tests validate both the happy path and edge cases for participant-related endpoints.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The tests are defined in the following file:&lt;br /&gt;
spec/requests/api/v1/participants_spec.rb&lt;br /&gt;
&lt;br /&gt;
The structure includes the following tested endpoints:&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/user/:user_id ===&lt;br /&gt;
&lt;br /&gt;
Description: Returns all participants associated with a given user.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns list of participants&lt;br /&gt;
* 404 Not Found – User ID does not exist&lt;br /&gt;
* 401 Unauthorized – Invalid or missing token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response is an array of participant objects.&lt;br /&gt;
* Each object contains correct user_id and assignment_id.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/assignment/:assignment_id ===&lt;br /&gt;
&lt;br /&gt;
Description: Returns all participants associated with a specific assignment.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns matching participants&lt;br /&gt;
* 404 Not Found – Assignment ID does not exist&lt;br /&gt;
* 401 Unauthorized – Token is invalid or missing&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response contains participants with matching assignment_id.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/:id ===&lt;br /&gt;
&lt;br /&gt;
Description: Retrieves a single participant by ID.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns the correct participant&lt;br /&gt;
* 404 Not Found – Invalid participant ID&lt;br /&gt;
* 401 Unauthorized – No or invalid token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* JSON contains user_id and assignment_id matching test data.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: DELETE /api/v1/participants/:id ===&lt;br /&gt;
&lt;br /&gt;
Description: Deletes a participant by ID.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 204 No Content – Participant deleted successfully&lt;br /&gt;
* 404 Not Found – Deleting a non-existent participant&lt;br /&gt;
* 401 Unauthorized – Missing or invalid auth token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response body is empty on successful deletion.&lt;br /&gt;
&lt;br /&gt;
=== Authentication ===&lt;br /&gt;
&lt;br /&gt;
Before each test, an admin login is performed, and a valid JWT token is captured and passed in the Authorization header for secure access.&lt;br /&gt;
before(:all) do&lt;br /&gt;
  post '/login', params: { user_name: 'admin2@example.com', password: 'password123' }&lt;br /&gt;
  @token = JSON.parse(response.body)['token']&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The token is used like so:&lt;br /&gt;
&lt;br /&gt;
let(:valid_headers) { { 'Authorization' =&amp;gt; &amp;quot;Bearer #{@token}&amp;quot; } }&lt;br /&gt;
&lt;br /&gt;
=== Error Handling Covered ===&lt;br /&gt;
&lt;br /&gt;
Each endpoint is tested for:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Valid request returns expected data.&lt;br /&gt;
* 404 Not Found – Invalid user_id, assignment_id, or participant_id.&lt;br /&gt;
* 401 Unauthorized – Missing or invalid JWT token.&lt;br /&gt;
&lt;br /&gt;
=== Benefits ===&lt;br /&gt;
&lt;br /&gt;
* Confidence in refactoring: Ensures controller changes don’t break expected behavior.&lt;br /&gt;
* Live API Docs: Swagger UI automatically reflects documented test cases.&lt;br /&gt;
* Security: Token-based auth is enforced and tested for all protected endpoints.&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://github.com/brianhhuynh38/expertiza-e2511/tree/main Github Repository]&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya@ncsu.edu)&lt;br /&gt;
* Brian Huynh (bhhuynh@ncsu.edu)&lt;br /&gt;
* Akhil Adusumilli (aadusum@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162643</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162643"/>
		<updated>2025-03-25T01:57:32Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* How it Works */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== SOLID Principles in participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The reimplementation of &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; follows several key SOLID design principles, promoting better structure, maintainability, and testability of the code.&lt;br /&gt;
&lt;br /&gt;
===  Single Responsibility Principle (SRP) ===&lt;br /&gt;
*A class should have only one reason to change.*&lt;br /&gt;
&lt;br /&gt;
The controller now only manages routing and API logic. Role-based permission logic is abstracted into a helper method (or strategy), and user creation is encapsulated using strong params.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
* &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; method handles only participant creation.&lt;br /&gt;
* &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; cleanly maps roles to permission flags.&lt;br /&gt;
* Deprecated methods like &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; were removed to reduce clutter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Open/Closed Principle (OCP) ===&lt;br /&gt;
*Software should be open for extension, but closed for modification.*&lt;br /&gt;
&lt;br /&gt;
The controller supports new roles or permission logic without modifying existing methods. By using &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; or a Strategy Pattern, the controller can support additional behaviors without structural changes.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* You can add new roles (e.g., Observer, Facilitator) by extending the permission logic externally.&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== API Testing with RSpec and Swagger ==&lt;br /&gt;
&lt;br /&gt;
As part of ensuring the stability and correctness of the newly reimplemented ParticipantsController, comprehensive API tests were added using RSpec and rswag (Swagger integration). These tests validate both the happy path and edge cases for participant-related endpoints.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The tests are defined in the following file:&lt;br /&gt;
spec/requests/api/v1/participants_spec.rb&lt;br /&gt;
&lt;br /&gt;
The structure includes the following tested endpoints:&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/user/:user_id ===&lt;br /&gt;
&lt;br /&gt;
Description: Returns all participants associated with a given user.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns list of participants&lt;br /&gt;
* 404 Not Found – User ID does not exist&lt;br /&gt;
* 401 Unauthorized – Invalid or missing token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response is an array of participant objects.&lt;br /&gt;
* Each object contains correct user_id and assignment_id.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/assignment/:assignment_id ===&lt;br /&gt;
&lt;br /&gt;
Description: Returns all participants associated with a specific assignment.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns matching participants&lt;br /&gt;
* 404 Not Found – Assignment ID does not exist&lt;br /&gt;
* 401 Unauthorized – Token is invalid or missing&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response contains participants with matching assignment_id.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/:id ===&lt;br /&gt;
&lt;br /&gt;
Description: Retrieves a single participant by ID.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns the correct participant&lt;br /&gt;
* 404 Not Found – Invalid participant ID&lt;br /&gt;
* 401 Unauthorized – No or invalid token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* JSON contains user_id and assignment_id matching test data.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: DELETE /api/v1/participants/:id ===&lt;br /&gt;
&lt;br /&gt;
Description: Deletes a participant by ID.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 204 No Content – Participant deleted successfully&lt;br /&gt;
* 404 Not Found – Deleting a non-existent participant&lt;br /&gt;
* 401 Unauthorized – Missing or invalid auth token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response body is empty on successful deletion.&lt;br /&gt;
&lt;br /&gt;
=== Authentication ===&lt;br /&gt;
&lt;br /&gt;
Before each test, an admin login is performed, and a valid JWT token is captured and passed in the Authorization header for secure access.&lt;br /&gt;
before(:all) do&lt;br /&gt;
  post '/login', params: { user_name: 'admin2@example.com', password: 'password123' }&lt;br /&gt;
  @token = JSON.parse(response.body)['token']&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The token is used like so:&lt;br /&gt;
&lt;br /&gt;
let(:valid_headers) { { 'Authorization' =&amp;gt; &amp;quot;Bearer #{@token}&amp;quot; } }&lt;br /&gt;
&lt;br /&gt;
=== Error Handling Covered ===&lt;br /&gt;
&lt;br /&gt;
Each endpoint is tested for:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Valid request returns expected data.&lt;br /&gt;
* 404 Not Found – Invalid user_id, assignment_id, or participant_id.&lt;br /&gt;
* 401 Unauthorized – Missing or invalid JWT token.&lt;br /&gt;
&lt;br /&gt;
=== Benefits ===&lt;br /&gt;
&lt;br /&gt;
* Confidence in refactoring: Ensures controller changes don’t break expected behavior.&lt;br /&gt;
* Live API Docs: Swagger UI automatically reflects documented test cases.&lt;br /&gt;
* Security: Token-based auth is enforced and tested for all protected endpoints.&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya@ncsu.edu)&lt;br /&gt;
* Brian Huynh (bhhuynh@ncsu.edu)&lt;br /&gt;
* Akhil Adusumilli (aadusum@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162634</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162634"/>
		<updated>2025-03-25T01:47:17Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Method: add */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== SOLID Principles in participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The reimplementation of &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; follows several key SOLID design principles, promoting better structure, maintainability, and testability of the code.&lt;br /&gt;
&lt;br /&gt;
===  Single Responsibility Principle (SRP) ===&lt;br /&gt;
*A class should have only one reason to change.*&lt;br /&gt;
&lt;br /&gt;
The controller now only manages routing and API logic. Role-based permission logic is abstracted into a helper method (or strategy), and user creation is encapsulated using strong params.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
* &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; method handles only participant creation.&lt;br /&gt;
* &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; cleanly maps roles to permission flags.&lt;br /&gt;
* Deprecated methods like &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; were removed to reduce clutter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Open/Closed Principle (OCP) ===&lt;br /&gt;
*Software should be open for extension, but closed for modification.*&lt;br /&gt;
&lt;br /&gt;
The controller supports new roles or permission logic without modifying existing methods. By using &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; or a Strategy Pattern, the controller can support additional behaviors without structural changes.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* You can add new roles (e.g., Observer, Facilitator) by extending the permission logic externally.&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== API Testing with RSpec and Swagger ==&lt;br /&gt;
&lt;br /&gt;
As part of ensuring the stability and correctness of the newly reimplemented ParticipantsController, comprehensive API tests were added using RSpec and rswag (Swagger integration). These tests validate both the happy path and edge cases for participant-related endpoints.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The tests are defined in the following file:&lt;br /&gt;
spec/requests/api/v1/participants_spec.rb&lt;br /&gt;
&lt;br /&gt;
The structure includes the following tested endpoints:&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/user/:user_id ===&lt;br /&gt;
&lt;br /&gt;
Description: Returns all participants associated with a given user.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns list of participants&lt;br /&gt;
* 404 Not Found – User ID does not exist&lt;br /&gt;
* 401 Unauthorized – Invalid or missing token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response is an array of participant objects.&lt;br /&gt;
* Each object contains correct user_id and assignment_id.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/assignment/:assignment_id ===&lt;br /&gt;
&lt;br /&gt;
Description: Returns all participants associated with a specific assignment.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns matching participants&lt;br /&gt;
* 404 Not Found – Assignment ID does not exist&lt;br /&gt;
* 401 Unauthorized – Token is invalid or missing&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response contains participants with matching assignment_id.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/:id ===&lt;br /&gt;
&lt;br /&gt;
Description: Retrieves a single participant by ID.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns the correct participant&lt;br /&gt;
* 404 Not Found – Invalid participant ID&lt;br /&gt;
* 401 Unauthorized – No or invalid token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* JSON contains user_id and assignment_id matching test data.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: DELETE /api/v1/participants/:id ===&lt;br /&gt;
&lt;br /&gt;
Description: Deletes a participant by ID.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 204 No Content – Participant deleted successfully&lt;br /&gt;
* 404 Not Found – Deleting a non-existent participant&lt;br /&gt;
* 401 Unauthorized – Missing or invalid auth token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response body is empty on successful deletion.&lt;br /&gt;
&lt;br /&gt;
=== Authentication ===&lt;br /&gt;
&lt;br /&gt;
Before each test, an admin login is performed, and a valid JWT token is captured and passed in the Authorization header for secure access.&lt;br /&gt;
before(:all) do&lt;br /&gt;
  post '/login', params: { user_name: 'admin2@example.com', password: 'password123' }&lt;br /&gt;
  @token = JSON.parse(response.body)['token']&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The token is used like so:&lt;br /&gt;
&lt;br /&gt;
let(:valid_headers) { { 'Authorization' =&amp;gt; &amp;quot;Bearer #{@token}&amp;quot; } }&lt;br /&gt;
&lt;br /&gt;
=== Error Handling Covered ===&lt;br /&gt;
&lt;br /&gt;
Each endpoint is tested for:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Valid request returns expected data.&lt;br /&gt;
* 404 Not Found – Invalid user_id, assignment_id, or participant_id.&lt;br /&gt;
* 401 Unauthorized – Missing or invalid JWT token.&lt;br /&gt;
&lt;br /&gt;
=== Benefits ===&lt;br /&gt;
&lt;br /&gt;
* Confidence in refactoring: Ensures controller changes don’t break expected behavior.&lt;br /&gt;
* Live API Docs: Swagger UI automatically reflects documented test cases.&lt;br /&gt;
* Security: Token-based auth is enforced and tested for all protected endpoints.&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya@ncsu.edu)&lt;br /&gt;
* Brian Huynh (bhhuynh@ncsu.edu)&lt;br /&gt;
* Akhil Adusumilli (aadusum@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162633</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162633"/>
		<updated>2025-03-25T01:46:53Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Example Test: Get Participants by User ID */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== SOLID Principles in participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The reimplementation of &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; follows several key SOLID design principles, promoting better structure, maintainability, and testability of the code.&lt;br /&gt;
&lt;br /&gt;
===  Single Responsibility Principle (SRP) ===&lt;br /&gt;
*A class should have only one reason to change.*&lt;br /&gt;
&lt;br /&gt;
The controller now only manages routing and API logic. Role-based permission logic is abstracted into a helper method (or strategy), and user creation is encapsulated using strong params.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
* &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; method handles only participant creation.&lt;br /&gt;
* &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; cleanly maps roles to permission flags.&lt;br /&gt;
* Deprecated methods like &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; were removed to reduce clutter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Open/Closed Principle (OCP) ===&lt;br /&gt;
*Software should be open for extension, but closed for modification.*&lt;br /&gt;
&lt;br /&gt;
The controller supports new roles or permission logic without modifying existing methods. By using &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; or a Strategy Pattern, the controller can support additional behaviors without structural changes.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* You can add new roles (e.g., Observer, Facilitator) by extending the permission logic externally.&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== API Testing with RSpec and Swagger ==&lt;br /&gt;
&lt;br /&gt;
As part of ensuring the stability and correctness of the newly reimplemented ParticipantsController, comprehensive API tests were added using RSpec and rswag (Swagger integration). These tests validate both the happy path and edge cases for participant-related endpoints.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The tests are defined in the following file:&lt;br /&gt;
spec/requests/api/v1/participants_spec.rb&lt;br /&gt;
&lt;br /&gt;
The structure includes the following tested endpoints:&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/user/:user_id ===&lt;br /&gt;
&lt;br /&gt;
Description: Returns all participants associated with a given user.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns list of participants&lt;br /&gt;
* 404 Not Found – User ID does not exist&lt;br /&gt;
* 401 Unauthorized – Invalid or missing token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response is an array of participant objects.&lt;br /&gt;
* Each object contains correct user_id and assignment_id.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/assignment/:assignment_id ===&lt;br /&gt;
&lt;br /&gt;
Description: Returns all participants associated with a specific assignment.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns matching participants&lt;br /&gt;
* 404 Not Found – Assignment ID does not exist&lt;br /&gt;
* 401 Unauthorized – Token is invalid or missing&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response contains participants with matching assignment_id.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/:id ===&lt;br /&gt;
&lt;br /&gt;
Description: Retrieves a single participant by ID.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns the correct participant&lt;br /&gt;
* 404 Not Found – Invalid participant ID&lt;br /&gt;
* 401 Unauthorized – No or invalid token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* JSON contains user_id and assignment_id matching test data.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: DELETE /api/v1/participants/:id ===&lt;br /&gt;
&lt;br /&gt;
Description: Deletes a participant by ID.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 204 No Content – Participant deleted successfully&lt;br /&gt;
* 404 Not Found – Deleting a non-existent participant&lt;br /&gt;
* 401 Unauthorized – Missing or invalid auth token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response body is empty on successful deletion.&lt;br /&gt;
&lt;br /&gt;
=== Authentication ===&lt;br /&gt;
&lt;br /&gt;
Before each test, an admin login is performed, and a valid JWT token is captured and passed in the Authorization header for secure access.&lt;br /&gt;
before(:all) do&lt;br /&gt;
  post '/login', params: { user_name: 'admin2@example.com', password: 'password123' }&lt;br /&gt;
  @token = JSON.parse(response.body)['token']&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The token is used like so:&lt;br /&gt;
&lt;br /&gt;
let(:valid_headers) { { 'Authorization' =&amp;gt; &amp;quot;Bearer #{@token}&amp;quot; } }&lt;br /&gt;
&lt;br /&gt;
=== Error Handling Covered ===&lt;br /&gt;
&lt;br /&gt;
Each endpoint is tested for:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Valid request returns expected data.&lt;br /&gt;
* 404 Not Found – Invalid user_id, assignment_id, or participant_id.&lt;br /&gt;
* 401 Unauthorized – Missing or invalid JWT token.&lt;br /&gt;
&lt;br /&gt;
=== Benefits ===&lt;br /&gt;
&lt;br /&gt;
* Confidence in refactoring: Ensures controller changes don’t break expected behavior.&lt;br /&gt;
* Live API Docs: Swagger UI automatically reflects documented test cases.&lt;br /&gt;
* Security: Token-based auth is enforced and tested for all protected endpoints.&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya@ncsu.edu)&lt;br /&gt;
* Brian Huynh (bhhuynh@ncsu.edu)&lt;br /&gt;
* Akhil Adusumilli (aadusum@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162628</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162628"/>
		<updated>2025-03-25T01:42:11Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Endpoint: GET /api/v1/participants/user/:user_id */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== SOLID Principles in participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The reimplementation of &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; follows several key SOLID design principles, promoting better structure, maintainability, and testability of the code.&lt;br /&gt;
&lt;br /&gt;
===  Single Responsibility Principle (SRP) ===&lt;br /&gt;
*A class should have only one reason to change.*&lt;br /&gt;
&lt;br /&gt;
The controller now only manages routing and API logic. Role-based permission logic is abstracted into a helper method (or strategy), and user creation is encapsulated using strong params.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
* &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; method handles only participant creation.&lt;br /&gt;
* &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; cleanly maps roles to permission flags.&lt;br /&gt;
* Deprecated methods like &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; were removed to reduce clutter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Open/Closed Principle (OCP) ===&lt;br /&gt;
*Software should be open for extension, but closed for modification.*&lt;br /&gt;
&lt;br /&gt;
The controller supports new roles or permission logic without modifying existing methods. By using &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; or a Strategy Pattern, the controller can support additional behaviors without structural changes.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* You can add new roles (e.g., Observer, Facilitator) by extending the permission logic externally.&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== API Testing with RSpec and Swagger ==&lt;br /&gt;
&lt;br /&gt;
As part of ensuring the stability and correctness of the newly reimplemented ParticipantsController, comprehensive API tests were added using RSpec and rswag (Swagger integration). These tests validate both the happy path and edge cases for participant-related endpoints.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The tests are defined in the following file:&lt;br /&gt;
spec/requests/api/v1/participants_spec.rb&lt;br /&gt;
&lt;br /&gt;
The structure includes the following tested endpoints:&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/user/:user_id ===&lt;br /&gt;
&lt;br /&gt;
Description: Returns all participants associated with a given user.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns list of participants&lt;br /&gt;
* 404 Not Found – User ID does not exist&lt;br /&gt;
* 401 Unauthorized – Invalid or missing token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response is an array of participant objects.&lt;br /&gt;
* Each object contains correct user_id and assignment_id.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/assignment/:assignment_id ===&lt;br /&gt;
&lt;br /&gt;
Description: Returns all participants associated with a specific assignment.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns matching participants&lt;br /&gt;
* 404 Not Found – Assignment ID does not exist&lt;br /&gt;
* 401 Unauthorized – Token is invalid or missing&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response contains participants with matching assignment_id.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/:id ===&lt;br /&gt;
&lt;br /&gt;
Description: Retrieves a single participant by ID.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns the correct participant&lt;br /&gt;
* 404 Not Found – Invalid participant ID&lt;br /&gt;
* 401 Unauthorized – No or invalid token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* JSON contains user_id and assignment_id matching test data.&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: DELETE /api/v1/participants/:id ===&lt;br /&gt;
&lt;br /&gt;
Description: Deletes a participant by ID.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 204 No Content – Participant deleted successfully&lt;br /&gt;
* 404 Not Found – Deleting a non-existent participant&lt;br /&gt;
* 401 Unauthorized – Missing or invalid auth token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response body is empty on successful deletion.&lt;br /&gt;
&lt;br /&gt;
=== Authentication ===&lt;br /&gt;
&lt;br /&gt;
Before each test, an admin login is performed, and a valid JWT token is captured and passed in the Authorization header for secure access.&lt;br /&gt;
before(:all) do&lt;br /&gt;
  post '/login', params: { user_name: 'admin2@example.com', password: 'password123' }&lt;br /&gt;
  @token = JSON.parse(response.body)['token']&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The token is used like so:&lt;br /&gt;
&lt;br /&gt;
let(:valid_headers) { { 'Authorization' =&amp;gt; &amp;quot;Bearer #{@token}&amp;quot; } }&lt;br /&gt;
&lt;br /&gt;
=== Example Test: Get Participants by User ID ===&lt;br /&gt;
&lt;br /&gt;
path '/api/v1/participants/user/{user_id}' do&lt;br /&gt;
  get 'Retrieve participants for a specific user' do&lt;br /&gt;
    parameter name: :user_id, in: :path, type: :integer&lt;br /&gt;
    parameter name: 'Authorization', in: :header, type: :string&lt;br /&gt;
&lt;br /&gt;
    response '200', 'Returns participants' do&lt;br /&gt;
      let(:user_id) { 4 }&lt;br /&gt;
      let(:'Authorization') { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
      run_test! do |response|&lt;br /&gt;
        data = JSON.parse(response.body)&lt;br /&gt;
        expect(data[0]['user_id']).to eq(4)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
=== Error Handling Covered ===&lt;br /&gt;
&lt;br /&gt;
Each endpoint is tested for:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Valid request returns expected data.&lt;br /&gt;
* 404 Not Found – Invalid user_id, assignment_id, or participant_id.&lt;br /&gt;
* 401 Unauthorized – Missing or invalid JWT token.&lt;br /&gt;
&lt;br /&gt;
=== Benefits ===&lt;br /&gt;
&lt;br /&gt;
* Confidence in refactoring: Ensures controller changes don’t break expected behavior.&lt;br /&gt;
* Live API Docs: Swagger UI automatically reflects documented test cases.&lt;br /&gt;
* Security: Token-based auth is enforced and tested for all protected endpoints.&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya@ncsu.edu)&lt;br /&gt;
* Brian Huynh (bhhuynh@ncsu.edu)&lt;br /&gt;
* Akhil Adusumilli (aadusum@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162625</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162625"/>
		<updated>2025-03-25T01:40:06Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Structure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== SOLID Principles in participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The reimplementation of &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; follows several key SOLID design principles, promoting better structure, maintainability, and testability of the code.&lt;br /&gt;
&lt;br /&gt;
===  Single Responsibility Principle (SRP) ===&lt;br /&gt;
*A class should have only one reason to change.*&lt;br /&gt;
&lt;br /&gt;
The controller now only manages routing and API logic. Role-based permission logic is abstracted into a helper method (or strategy), and user creation is encapsulated using strong params.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
* &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; method handles only participant creation.&lt;br /&gt;
* &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; cleanly maps roles to permission flags.&lt;br /&gt;
* Deprecated methods like &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; were removed to reduce clutter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Open/Closed Principle (OCP) ===&lt;br /&gt;
*Software should be open for extension, but closed for modification.*&lt;br /&gt;
&lt;br /&gt;
The controller supports new roles or permission logic without modifying existing methods. By using &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; or a Strategy Pattern, the controller can support additional behaviors without structural changes.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* You can add new roles (e.g., Observer, Facilitator) by extending the permission logic externally.&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== API Testing with RSpec and Swagger ==&lt;br /&gt;
&lt;br /&gt;
As part of ensuring the stability and correctness of the newly reimplemented ParticipantsController, comprehensive API tests were added using RSpec and rswag (Swagger integration). These tests validate both the happy path and edge cases for participant-related endpoints.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The tests are defined in the following file:&lt;br /&gt;
spec/requests/api/v1/participants_spec.rb&lt;br /&gt;
&lt;br /&gt;
The structure includes the following tested endpoints:&lt;br /&gt;
&lt;br /&gt;
=== Endpoint: GET /api/v1/participants/user/:user_id ===&lt;br /&gt;
&lt;br /&gt;
Description: Returns all participants associated with a given user.&lt;br /&gt;
&lt;br /&gt;
Test Coverage:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Returns list of participants&lt;br /&gt;
* 404 Not Found – User ID does not exist&lt;br /&gt;
* 401 Unauthorized – Invalid or missing token&lt;br /&gt;
&lt;br /&gt;
Assertions:&lt;br /&gt;
&lt;br /&gt;
* Response is an array of participant objects.&lt;br /&gt;
* Each object contains correct user_id and assignment_id.&lt;br /&gt;
&lt;br /&gt;
=== Authentication ===&lt;br /&gt;
&lt;br /&gt;
Before each test, an admin login is performed, and a valid JWT token is captured and passed in the Authorization header for secure access.&lt;br /&gt;
before(:all) do&lt;br /&gt;
  post '/login', params: { user_name: 'admin2@example.com', password: 'password123' }&lt;br /&gt;
  @token = JSON.parse(response.body)['token']&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The token is used like so:&lt;br /&gt;
&lt;br /&gt;
let(:valid_headers) { { 'Authorization' =&amp;gt; &amp;quot;Bearer #{@token}&amp;quot; } }&lt;br /&gt;
&lt;br /&gt;
=== Example Test: Get Participants by User ID ===&lt;br /&gt;
&lt;br /&gt;
path '/api/v1/participants/user/{user_id}' do&lt;br /&gt;
  get 'Retrieve participants for a specific user' do&lt;br /&gt;
    parameter name: :user_id, in: :path, type: :integer&lt;br /&gt;
    parameter name: 'Authorization', in: :header, type: :string&lt;br /&gt;
&lt;br /&gt;
    response '200', 'Returns participants' do&lt;br /&gt;
      let(:user_id) { 4 }&lt;br /&gt;
      let(:'Authorization') { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
      run_test! do |response|&lt;br /&gt;
        data = JSON.parse(response.body)&lt;br /&gt;
        expect(data[0]['user_id']).to eq(4)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
=== Error Handling Covered ===&lt;br /&gt;
&lt;br /&gt;
Each endpoint is tested for:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Valid request returns expected data.&lt;br /&gt;
* 404 Not Found – Invalid user_id, assignment_id, or participant_id.&lt;br /&gt;
* 401 Unauthorized – Missing or invalid JWT token.&lt;br /&gt;
&lt;br /&gt;
=== Benefits ===&lt;br /&gt;
&lt;br /&gt;
* Confidence in refactoring: Ensures controller changes don’t break expected behavior.&lt;br /&gt;
* Live API Docs: Swagger UI automatically reflects documented test cases.&lt;br /&gt;
* Security: Token-based auth is enforced and tested for all protected endpoints.&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya@ncsu.edu)&lt;br /&gt;
* Brian Huynh (bhhuynh@ncsu.edu)&lt;br /&gt;
* Akhil Adusumilli (aadusum@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162618</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162618"/>
		<updated>2025-03-25T01:35:45Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Authentication */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== SOLID Principles in participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The reimplementation of &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; follows several key SOLID design principles, promoting better structure, maintainability, and testability of the code.&lt;br /&gt;
&lt;br /&gt;
===  Single Responsibility Principle (SRP) ===&lt;br /&gt;
*A class should have only one reason to change.*&lt;br /&gt;
&lt;br /&gt;
The controller now only manages routing and API logic. Role-based permission logic is abstracted into a helper method (or strategy), and user creation is encapsulated using strong params.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
* &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; method handles only participant creation.&lt;br /&gt;
* &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; cleanly maps roles to permission flags.&lt;br /&gt;
* Deprecated methods like &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; were removed to reduce clutter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Open/Closed Principle (OCP) ===&lt;br /&gt;
*Software should be open for extension, but closed for modification.*&lt;br /&gt;
&lt;br /&gt;
The controller supports new roles or permission logic without modifying existing methods. By using &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; or a Strategy Pattern, the controller can support additional behaviors without structural changes.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* You can add new roles (e.g., Observer, Facilitator) by extending the permission logic externally.&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== API Testing with RSpec and Swagger ==&lt;br /&gt;
&lt;br /&gt;
As part of ensuring the stability and correctness of the newly reimplemented ParticipantsController, comprehensive API tests were added using RSpec and rswag (Swagger integration). These tests validate both the happy path and edge cases for participant-related endpoints.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The tests are defined in the following file:&lt;br /&gt;
spec/requests/api/v1/participants_spec.rb&lt;br /&gt;
&lt;br /&gt;
The structure includes the following tested endpoints:&lt;br /&gt;
&lt;br /&gt;
* GET /api/v1/participants/user/:user_id – Fetch participants for a user&lt;br /&gt;
* GET /api/v1/participants/assignment/:assignment_id – Fetch participants for an assignment&lt;br /&gt;
* GET /api/v1/participants/:id – Fetch specific participant&lt;br /&gt;
* DELETE /api/v1/participants/:id – Delete a participant&lt;br /&gt;
=== Authentication ===&lt;br /&gt;
&lt;br /&gt;
Before each test, an admin login is performed, and a valid JWT token is captured and passed in the Authorization header for secure access.&lt;br /&gt;
before(:all) do&lt;br /&gt;
  post '/login', params: { user_name: 'admin2@example.com', password: 'password123' }&lt;br /&gt;
  @token = JSON.parse(response.body)['token']&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The token is used like so:&lt;br /&gt;
&lt;br /&gt;
let(:valid_headers) { { 'Authorization' =&amp;gt; &amp;quot;Bearer #{@token}&amp;quot; } }&lt;br /&gt;
&lt;br /&gt;
=== Example Test: Get Participants by User ID ===&lt;br /&gt;
&lt;br /&gt;
path '/api/v1/participants/user/{user_id}' do&lt;br /&gt;
  get 'Retrieve participants for a specific user' do&lt;br /&gt;
    parameter name: :user_id, in: :path, type: :integer&lt;br /&gt;
    parameter name: 'Authorization', in: :header, type: :string&lt;br /&gt;
&lt;br /&gt;
    response '200', 'Returns participants' do&lt;br /&gt;
      let(:user_id) { 4 }&lt;br /&gt;
      let(:'Authorization') { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
      run_test! do |response|&lt;br /&gt;
        data = JSON.parse(response.body)&lt;br /&gt;
        expect(data[0]['user_id']).to eq(4)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
=== Error Handling Covered ===&lt;br /&gt;
&lt;br /&gt;
Each endpoint is tested for:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Valid request returns expected data.&lt;br /&gt;
* 404 Not Found – Invalid user_id, assignment_id, or participant_id.&lt;br /&gt;
* 401 Unauthorized – Missing or invalid JWT token.&lt;br /&gt;
&lt;br /&gt;
=== Benefits ===&lt;br /&gt;
&lt;br /&gt;
* Confidence in refactoring: Ensures controller changes don’t break expected behavior.&lt;br /&gt;
* Live API Docs: Swagger UI automatically reflects documented test cases.&lt;br /&gt;
* Security: Token-based auth is enforced and tested for all protected endpoints.&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya@ncsu.edu)&lt;br /&gt;
* Brian Huynh (bhhuynh@ncsu.edu)&lt;br /&gt;
* Akhil Adusumilli (aadusum@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162616</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162616"/>
		<updated>2025-03-25T01:35:12Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Benefits */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== SOLID Principles in participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The reimplementation of &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; follows several key SOLID design principles, promoting better structure, maintainability, and testability of the code.&lt;br /&gt;
&lt;br /&gt;
===  Single Responsibility Principle (SRP) ===&lt;br /&gt;
*A class should have only one reason to change.*&lt;br /&gt;
&lt;br /&gt;
The controller now only manages routing and API logic. Role-based permission logic is abstracted into a helper method (or strategy), and user creation is encapsulated using strong params.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
* &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; method handles only participant creation.&lt;br /&gt;
* &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; cleanly maps roles to permission flags.&lt;br /&gt;
* Deprecated methods like &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; were removed to reduce clutter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Open/Closed Principle (OCP) ===&lt;br /&gt;
*Software should be open for extension, but closed for modification.*&lt;br /&gt;
&lt;br /&gt;
The controller supports new roles or permission logic without modifying existing methods. By using &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; or a Strategy Pattern, the controller can support additional behaviors without structural changes.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* You can add new roles (e.g., Observer, Facilitator) by extending the permission logic externally.&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== API Testing with RSpec and Swagger ==&lt;br /&gt;
&lt;br /&gt;
As part of ensuring the stability and correctness of the newly reimplemented ParticipantsController, comprehensive API tests were added using RSpec and rswag (Swagger integration). These tests validate both the happy path and edge cases for participant-related endpoints.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The tests are defined in the following file:&lt;br /&gt;
spec/requests/api/v1/participants_spec.rb&lt;br /&gt;
&lt;br /&gt;
The structure includes the following tested endpoints:&lt;br /&gt;
&lt;br /&gt;
* GET /api/v1/participants/user/:user_id – Fetch participants for a user&lt;br /&gt;
* GET /api/v1/participants/assignment/:assignment_id – Fetch participants for an assignment&lt;br /&gt;
* GET /api/v1/participants/:id – Fetch specific participant&lt;br /&gt;
* DELETE /api/v1/participants/:id – Delete a participant&lt;br /&gt;
=== Authentication ===&lt;br /&gt;
&lt;br /&gt;
Before each test, an admin login is performed, and a valid JWT token is captured and passed in the Authorization header for secure access.&lt;br /&gt;
before(:all) do&lt;br /&gt;
  post '/login', params: { user_name: 'admin2@example.com', password: 'password123' }&lt;br /&gt;
  @token = JSON.parse(response.body)['token']&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
The token is used like so:&lt;br /&gt;
let(:valid_headers) { { 'Authorization' =&amp;gt; &amp;quot;Bearer #{@token}&amp;quot; } }&lt;br /&gt;
&lt;br /&gt;
=== Example Test: Get Participants by User ID ===&lt;br /&gt;
&lt;br /&gt;
path '/api/v1/participants/user/{user_id}' do&lt;br /&gt;
  get 'Retrieve participants for a specific user' do&lt;br /&gt;
    parameter name: :user_id, in: :path, type: :integer&lt;br /&gt;
    parameter name: 'Authorization', in: :header, type: :string&lt;br /&gt;
&lt;br /&gt;
    response '200', 'Returns participants' do&lt;br /&gt;
      let(:user_id) { 4 }&lt;br /&gt;
      let(:'Authorization') { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
      run_test! do |response|&lt;br /&gt;
        data = JSON.parse(response.body)&lt;br /&gt;
        expect(data[0]['user_id']).to eq(4)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
=== Error Handling Covered ===&lt;br /&gt;
&lt;br /&gt;
Each endpoint is tested for:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Valid request returns expected data.&lt;br /&gt;
* 404 Not Found – Invalid user_id, assignment_id, or participant_id.&lt;br /&gt;
* 401 Unauthorized – Missing or invalid JWT token.&lt;br /&gt;
&lt;br /&gt;
=== Benefits ===&lt;br /&gt;
&lt;br /&gt;
* Confidence in refactoring: Ensures controller changes don’t break expected behavior.&lt;br /&gt;
* Live API Docs: Swagger UI automatically reflects documented test cases.&lt;br /&gt;
* Security: Token-based auth is enforced and tested for all protected endpoints.&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya@ncsu.edu)&lt;br /&gt;
* Brian Huynh (bhhuynh@ncsu.edu)&lt;br /&gt;
* Akhil Adusumilli (aadusum@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162615</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162615"/>
		<updated>2025-03-25T01:34:57Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Error Handling Covered */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== SOLID Principles in participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The reimplementation of &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; follows several key SOLID design principles, promoting better structure, maintainability, and testability of the code.&lt;br /&gt;
&lt;br /&gt;
===  Single Responsibility Principle (SRP) ===&lt;br /&gt;
*A class should have only one reason to change.*&lt;br /&gt;
&lt;br /&gt;
The controller now only manages routing and API logic. Role-based permission logic is abstracted into a helper method (or strategy), and user creation is encapsulated using strong params.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
* &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; method handles only participant creation.&lt;br /&gt;
* &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; cleanly maps roles to permission flags.&lt;br /&gt;
* Deprecated methods like &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; were removed to reduce clutter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Open/Closed Principle (OCP) ===&lt;br /&gt;
*Software should be open for extension, but closed for modification.*&lt;br /&gt;
&lt;br /&gt;
The controller supports new roles or permission logic without modifying existing methods. By using &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; or a Strategy Pattern, the controller can support additional behaviors without structural changes.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* You can add new roles (e.g., Observer, Facilitator) by extending the permission logic externally.&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== API Testing with RSpec and Swagger ==&lt;br /&gt;
&lt;br /&gt;
As part of ensuring the stability and correctness of the newly reimplemented ParticipantsController, comprehensive API tests were added using RSpec and rswag (Swagger integration). These tests validate both the happy path and edge cases for participant-related endpoints.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The tests are defined in the following file:&lt;br /&gt;
spec/requests/api/v1/participants_spec.rb&lt;br /&gt;
&lt;br /&gt;
The structure includes the following tested endpoints:&lt;br /&gt;
&lt;br /&gt;
* GET /api/v1/participants/user/:user_id – Fetch participants for a user&lt;br /&gt;
* GET /api/v1/participants/assignment/:assignment_id – Fetch participants for an assignment&lt;br /&gt;
* GET /api/v1/participants/:id – Fetch specific participant&lt;br /&gt;
* DELETE /api/v1/participants/:id – Delete a participant&lt;br /&gt;
=== Authentication ===&lt;br /&gt;
&lt;br /&gt;
Before each test, an admin login is performed, and a valid JWT token is captured and passed in the Authorization header for secure access.&lt;br /&gt;
before(:all) do&lt;br /&gt;
  post '/login', params: { user_name: 'admin2@example.com', password: 'password123' }&lt;br /&gt;
  @token = JSON.parse(response.body)['token']&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
The token is used like so:&lt;br /&gt;
let(:valid_headers) { { 'Authorization' =&amp;gt; &amp;quot;Bearer #{@token}&amp;quot; } }&lt;br /&gt;
&lt;br /&gt;
=== Example Test: Get Participants by User ID ===&lt;br /&gt;
&lt;br /&gt;
path '/api/v1/participants/user/{user_id}' do&lt;br /&gt;
  get 'Retrieve participants for a specific user' do&lt;br /&gt;
    parameter name: :user_id, in: :path, type: :integer&lt;br /&gt;
    parameter name: 'Authorization', in: :header, type: :string&lt;br /&gt;
&lt;br /&gt;
    response '200', 'Returns participants' do&lt;br /&gt;
      let(:user_id) { 4 }&lt;br /&gt;
      let(:'Authorization') { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
      run_test! do |response|&lt;br /&gt;
        data = JSON.parse(response.body)&lt;br /&gt;
        expect(data[0]['user_id']).to eq(4)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
=== Error Handling Covered ===&lt;br /&gt;
&lt;br /&gt;
Each endpoint is tested for:&lt;br /&gt;
&lt;br /&gt;
* 200 OK – Valid request returns expected data.&lt;br /&gt;
* 404 Not Found – Invalid user_id, assignment_id, or participant_id.&lt;br /&gt;
* 401 Unauthorized – Missing or invalid JWT token.&lt;br /&gt;
&lt;br /&gt;
=== Benefits ===&lt;br /&gt;
&lt;br /&gt;
Confidence in refactoring: Ensures controller changes don’t break expected behavior.&lt;br /&gt;
Live API Docs: Swagger UI automatically reflects documented test cases.&lt;br /&gt;
Security: Token-based auth is enforced and tested for all protected endpoints.&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya@ncsu.edu)&lt;br /&gt;
* Brian Huynh (bhhuynh@ncsu.edu)&lt;br /&gt;
* Akhil Adusumilli (aadusum@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162612</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162612"/>
		<updated>2025-03-25T01:34:33Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* API Testing with RSpec and Swagger */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== SOLID Principles in participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The reimplementation of &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; follows several key SOLID design principles, promoting better structure, maintainability, and testability of the code.&lt;br /&gt;
&lt;br /&gt;
===  Single Responsibility Principle (SRP) ===&lt;br /&gt;
*A class should have only one reason to change.*&lt;br /&gt;
&lt;br /&gt;
The controller now only manages routing and API logic. Role-based permission logic is abstracted into a helper method (or strategy), and user creation is encapsulated using strong params.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
* &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; method handles only participant creation.&lt;br /&gt;
* &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; cleanly maps roles to permission flags.&lt;br /&gt;
* Deprecated methods like &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; were removed to reduce clutter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Open/Closed Principle (OCP) ===&lt;br /&gt;
*Software should be open for extension, but closed for modification.*&lt;br /&gt;
&lt;br /&gt;
The controller supports new roles or permission logic without modifying existing methods. By using &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; or a Strategy Pattern, the controller can support additional behaviors without structural changes.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* You can add new roles (e.g., Observer, Facilitator) by extending the permission logic externally.&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== API Testing with RSpec and Swagger ==&lt;br /&gt;
&lt;br /&gt;
As part of ensuring the stability and correctness of the newly reimplemented ParticipantsController, comprehensive API tests were added using RSpec and rswag (Swagger integration). These tests validate both the happy path and edge cases for participant-related endpoints.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The tests are defined in the following file:&lt;br /&gt;
spec/requests/api/v1/participants_spec.rb&lt;br /&gt;
&lt;br /&gt;
The structure includes the following tested endpoints:&lt;br /&gt;
&lt;br /&gt;
* GET /api/v1/participants/user/:user_id – Fetch participants for a user&lt;br /&gt;
* GET /api/v1/participants/assignment/:assignment_id – Fetch participants for an assignment&lt;br /&gt;
* GET /api/v1/participants/:id – Fetch specific participant&lt;br /&gt;
* DELETE /api/v1/participants/:id – Delete a participant&lt;br /&gt;
=== Authentication ===&lt;br /&gt;
&lt;br /&gt;
Before each test, an admin login is performed, and a valid JWT token is captured and passed in the Authorization header for secure access.&lt;br /&gt;
before(:all) do&lt;br /&gt;
  post '/login', params: { user_name: 'admin2@example.com', password: 'password123' }&lt;br /&gt;
  @token = JSON.parse(response.body)['token']&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
The token is used like so:&lt;br /&gt;
let(:valid_headers) { { 'Authorization' =&amp;gt; &amp;quot;Bearer #{@token}&amp;quot; } }&lt;br /&gt;
&lt;br /&gt;
=== Example Test: Get Participants by User ID ===&lt;br /&gt;
&lt;br /&gt;
path '/api/v1/participants/user/{user_id}' do&lt;br /&gt;
  get 'Retrieve participants for a specific user' do&lt;br /&gt;
    parameter name: :user_id, in: :path, type: :integer&lt;br /&gt;
    parameter name: 'Authorization', in: :header, type: :string&lt;br /&gt;
&lt;br /&gt;
    response '200', 'Returns participants' do&lt;br /&gt;
      let(:user_id) { 4 }&lt;br /&gt;
      let(:'Authorization') { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
      run_test! do |response|&lt;br /&gt;
        data = JSON.parse(response.body)&lt;br /&gt;
        expect(data[0]['user_id']).to eq(4)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
=== Error Handling Covered ===&lt;br /&gt;
&lt;br /&gt;
Each endpoint is tested for:&lt;br /&gt;
&lt;br /&gt;
200 OK – Valid request returns expected data.&lt;br /&gt;
404 Not Found – Invalid user_id, assignment_id, or participant_id.&lt;br /&gt;
401 Unauthorized – Missing or invalid JWT token.&lt;br /&gt;
=== Benefits ===&lt;br /&gt;
&lt;br /&gt;
Confidence in refactoring: Ensures controller changes don’t break expected behavior.&lt;br /&gt;
Live API Docs: Swagger UI automatically reflects documented test cases.&lt;br /&gt;
Security: Token-based auth is enforced and tested for all protected endpoints.&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya@ncsu.edu)&lt;br /&gt;
* Brian Huynh (bhhuynh@ncsu.edu)&lt;br /&gt;
* Akhil Adusumilli (aadusum@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162608</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162608"/>
		<updated>2025-03-25T01:33:06Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* API Testing with RSpec and Swagger */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== SOLID Principles in participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The reimplementation of &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; follows several key SOLID design principles, promoting better structure, maintainability, and testability of the code.&lt;br /&gt;
&lt;br /&gt;
===  Single Responsibility Principle (SRP) ===&lt;br /&gt;
*A class should have only one reason to change.*&lt;br /&gt;
&lt;br /&gt;
The controller now only manages routing and API logic. Role-based permission logic is abstracted into a helper method (or strategy), and user creation is encapsulated using strong params.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
* &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; method handles only participant creation.&lt;br /&gt;
* &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; cleanly maps roles to permission flags.&lt;br /&gt;
* Deprecated methods like &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; were removed to reduce clutter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Open/Closed Principle (OCP) ===&lt;br /&gt;
*Software should be open for extension, but closed for modification.*&lt;br /&gt;
&lt;br /&gt;
The controller supports new roles or permission logic without modifying existing methods. By using &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; or a Strategy Pattern, the controller can support additional behaviors without structural changes.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* You can add new roles (e.g., Observer, Facilitator) by extending the permission logic externally.&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== API Testing with RSpec and Swagger ==&lt;br /&gt;
&lt;br /&gt;
As part of ensuring the stability and correctness of the newly reimplemented ParticipantsController, comprehensive API tests were added using RSpec and rswag (Swagger integration). These tests validate both the happy path and edge cases for participant-related endpoints.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The tests are defined in the following file:&lt;br /&gt;
spec/requests/api/v1/participants_spec.rb&lt;br /&gt;
&lt;br /&gt;
The structure includes the following tested endpoints:&lt;br /&gt;
&lt;br /&gt;
* GET /api/v1/participants/user/:user_id – Fetch participants for a user&lt;br /&gt;
* GET /api/v1/participants/assignment/:assignment_id – Fetch participants for an assignment&lt;br /&gt;
* GET /api/v1/participants/:id – Fetch specific participant&lt;br /&gt;
* DELETE /api/v1/participants/:id – Delete a participant&lt;br /&gt;
=== Authentication ===&lt;br /&gt;
&lt;br /&gt;
Before each test, an admin login is performed, and a valid JWT token is captured and passed in the Authorization header for secure access.&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya@ncsu.edu)&lt;br /&gt;
* Brian Huynh (bhhuynh@ncsu.edu)&lt;br /&gt;
* Akhil Adusumilli (aadusum@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162605</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162605"/>
		<updated>2025-03-25T01:32:00Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Role-Based Strategy Pattern */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== SOLID Principles in participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The reimplementation of &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; follows several key SOLID design principles, promoting better structure, maintainability, and testability of the code.&lt;br /&gt;
&lt;br /&gt;
===  Single Responsibility Principle (SRP) ===&lt;br /&gt;
*A class should have only one reason to change.*&lt;br /&gt;
&lt;br /&gt;
The controller now only manages routing and API logic. Role-based permission logic is abstracted into a helper method (or strategy), and user creation is encapsulated using strong params.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
* &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; method handles only participant creation.&lt;br /&gt;
* &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; cleanly maps roles to permission flags.&lt;br /&gt;
* Deprecated methods like &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; were removed to reduce clutter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Open/Closed Principle (OCP) ===&lt;br /&gt;
*Software should be open for extension, but closed for modification.*&lt;br /&gt;
&lt;br /&gt;
The controller supports new roles or permission logic without modifying existing methods. By using &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; or a Strategy Pattern, the controller can support additional behaviors without structural changes.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* You can add new roles (e.g., Observer, Facilitator) by extending the permission logic externally.&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== API Testing with RSpec and Swagger ==&lt;br /&gt;
&lt;br /&gt;
As part of ensuring the stability and correctness of the newly reimplemented ParticipantsController, comprehensive API tests were added using RSpec and rswag (Swagger integration). These tests validate both the happy path and edge cases for participant-related endpoints.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The tests are defined in the following file:&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya@ncsu.edu)&lt;br /&gt;
* Brian Huynh (bhhuynh@ncsu.edu)&lt;br /&gt;
* Akhil Adusumilli (aadusum@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162596</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162596"/>
		<updated>2025-03-25T01:27:00Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Team Members */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== SOLID Principles in participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The reimplementation of &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; follows several key SOLID design principles, promoting better structure, maintainability, and testability of the code.&lt;br /&gt;
&lt;br /&gt;
===  Single Responsibility Principle (SRP) ===&lt;br /&gt;
*A class should have only one reason to change.*&lt;br /&gt;
&lt;br /&gt;
The controller now only manages routing and API logic. Role-based permission logic is abstracted into a helper method (or strategy), and user creation is encapsulated using strong params.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
* &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; method handles only participant creation.&lt;br /&gt;
* &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; cleanly maps roles to permission flags.&lt;br /&gt;
* Deprecated methods like &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; were removed to reduce clutter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Open/Closed Principle (OCP) ===&lt;br /&gt;
*Software should be open for extension, but closed for modification.*&lt;br /&gt;
&lt;br /&gt;
The controller supports new roles or permission logic without modifying existing methods. By using &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; or a Strategy Pattern, the controller can support additional behaviors without structural changes.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* You can add new roles (e.g., Observer, Facilitator) by extending the permission logic externally.&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya@ncsu.edu)&lt;br /&gt;
* Brian Huynh (bhhuynh@ncsu.edu)&lt;br /&gt;
* Akhil Adusumilli (aadusum@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162501</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162501"/>
		<updated>2025-03-25T00:06:42Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* SOLID Principles in participants_controller.rb */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== SOLID Principles in participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The reimplementation of &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; follows several key SOLID design principles, promoting better structure, maintainability, and testability of the code.&lt;br /&gt;
&lt;br /&gt;
===  Single Responsibility Principle (SRP) ===&lt;br /&gt;
*A class should have only one reason to change.*&lt;br /&gt;
&lt;br /&gt;
The controller now only manages routing and API logic. Role-based permission logic is abstracted into a helper method (or strategy), and user creation is encapsulated using strong params.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
* &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; method handles only participant creation.&lt;br /&gt;
* &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; cleanly maps roles to permission flags.&lt;br /&gt;
* Deprecated methods like &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; were removed to reduce clutter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Open/Closed Principle (OCP) ===&lt;br /&gt;
*Software should be open for extension, but closed for modification.*&lt;br /&gt;
&lt;br /&gt;
The controller supports new roles or permission logic without modifying existing methods. By using &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; or a Strategy Pattern, the controller can support additional behaviors without structural changes.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* You can add new roles (e.g., Observer, Facilitator) by extending the permission logic externally.&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya)&lt;br /&gt;
* Brian Huynh (bhhuynh)&lt;br /&gt;
* Akhil Adusumilli (aadusum)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162500</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162500"/>
		<updated>2025-03-25T00:06:20Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* SOLID Principles in participants_controller.rb */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== SOLID Principles in participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The reimplementation of &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; follows several key SOLID design principles, promoting better structure, maintainability, and testability of the code.&lt;br /&gt;
&lt;br /&gt;
===  Single Responsibility Principle (SRP) ===&lt;br /&gt;
*A class should have only one reason to change.*&lt;br /&gt;
&lt;br /&gt;
The controller now only manages routing and API logic. Role-based permission logic is abstracted into a helper method (or strategy), and user creation is encapsulated using strong params.&lt;br /&gt;
&lt;br /&gt;
**Examples:**&lt;br /&gt;
* &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; method handles only participant creation.&lt;br /&gt;
* &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; cleanly maps roles to permission flags.&lt;br /&gt;
* Deprecated methods like &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; were removed to reduce clutter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Open/Closed Principle (OCP) ===&lt;br /&gt;
*Software should be open for extension, but closed for modification.*&lt;br /&gt;
&lt;br /&gt;
The controller supports new roles or permission logic without modifying existing methods. By using &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; or a Strategy Pattern, the controller can support additional behaviors without structural changes.&lt;br /&gt;
&lt;br /&gt;
**Example:**&lt;br /&gt;
* You can add new roles (e.g., Observer, Facilitator) by extending the permission logic externally.&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya)&lt;br /&gt;
* Brian Huynh (bhhuynh)&lt;br /&gt;
* Akhil Adusumilli (aadusum)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162499</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162499"/>
		<updated>2025-03-25T00:06:05Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* participants_helper.rb Methods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== SOLID Principles in participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The reimplementation of &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; follows several key SOLID design principles, promoting better structure, maintainability, and testability of the code.&lt;br /&gt;
&lt;br /&gt;
===  Single Responsibility Principle (SRP) ===&lt;br /&gt;
*A class should have only one reason to change.*&lt;br /&gt;
&lt;br /&gt;
The controller now only manages routing and API logic. Role-based permission logic is abstracted into a helper method (or strategy), and user creation is encapsulated using strong params.&lt;br /&gt;
&lt;br /&gt;
**Examples:**&lt;br /&gt;
* &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; method handles only participant creation.&lt;br /&gt;
* &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; cleanly maps roles to permission flags.&lt;br /&gt;
* Deprecated methods like &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; were removed to reduce clutter.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
===  Open/Closed Principle (OCP) ===&lt;br /&gt;
*Software should be open for extension, but closed for modification.*&lt;br /&gt;
&lt;br /&gt;
The controller supports new roles or permission logic without modifying existing methods. By using &amp;lt;code&amp;gt;participant_permissions&amp;lt;/code&amp;gt; or a Strategy Pattern, the controller can support additional behaviors without structural changes.&lt;br /&gt;
&lt;br /&gt;
**Example:**&lt;br /&gt;
* You can add new roles (e.g., Observer, Facilitator) by extending the permission logic externally.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya)&lt;br /&gt;
* Brian Huynh (bhhuynh)&lt;br /&gt;
* Akhil Adusumilli (aadusum)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162498</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162498"/>
		<updated>2025-03-25T00:05:20Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* participants_helper.rb Methods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya)&lt;br /&gt;
* Brian Huynh (bhhuynh)&lt;br /&gt;
* Akhil Adusumilli (aadusum)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162497</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162497"/>
		<updated>2025-03-25T00:04:48Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* participants_helper.rb Methods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class Api::V1::ParticipantsController &amp;lt; ApplicationController&lt;br /&gt;
  include ParticipantsHelper&lt;br /&gt;
  # autocomplete :user, :name&lt;br /&gt;
  def index&lt;br /&gt;
    participants = Participant.all&lt;br /&gt;
    render json: participants&lt;br /&gt;
  end&lt;br /&gt;
  # ************************************************************&lt;br /&gt;
  #keeping this commented as to test&lt;br /&gt;
  # def action_allowed?&lt;br /&gt;
  #   if %w[change_handle update_duties].include? params[:action]&lt;br /&gt;
  #     current_user_has_student_privileges?&lt;br /&gt;
  #   else&lt;br /&gt;
  #     current_user_has_ta_privileges?&lt;br /&gt;
  #   end&lt;br /&gt;
  # end&lt;br /&gt;
  # ************************************************************&lt;br /&gt;
  #redundant by may be required later&lt;br /&gt;
  # def action_allowed?&lt;br /&gt;
  #   has_required_role?('Teaching Assistant')&lt;br /&gt;
  # end&lt;br /&gt;
  # ************************************************************&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @participant = Participant.new(participant_params)&lt;br /&gt;
    if @participant.save&lt;br /&gt;
      render json: @participant, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: { errors: @participant.errors.full_messages }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_participant, only: [:show, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /api/v1/participants/:id&lt;br /&gt;
  def show&lt;br /&gt;
    render json: @participant&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  #getting the user by user_index and retrive and how on swagger ui&lt;br /&gt;
  def user_index&lt;br /&gt;
    participants = Participant.where(user_id: params[:user_id])&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  #updating the participant by request body of  example { &amp;quot;can_submit&amp;quot;: true, &amp;quot;can_review&amp;quot;: true}&lt;br /&gt;
  def update&lt;br /&gt;
    if @participant.update(participant_params)&lt;br /&gt;
      render json: @participant, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { errors: @participant.errors.full_messages }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  #destroying the user by the id of the specific user&lt;br /&gt;
  def destroy&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
    participant.destroy&lt;br /&gt;
    render json: { message: &amp;quot;Participant deleted successfully&amp;quot; }, status: :ok&lt;br /&gt;
  rescue ActiveRecord::RecordNotFound&lt;br /&gt;
    render json: { error: &amp;quot;Participant not found&amp;quot; }, status: :not_found&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  #finding partcipant by assignment id&lt;br /&gt;
  def assignment_index&lt;br /&gt;
    participants = Participant.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    render json: participants, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # def add&lt;br /&gt;
  #   handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  #   assignment_id = params[:id]&lt;br /&gt;
  #   authorization = params[:authorization]&lt;br /&gt;
  #   user_name = params[:user][:name]&lt;br /&gt;
  &lt;br /&gt;
  #   user = User.find_by(name: user_name)&lt;br /&gt;
  #   return render json: { error: &amp;quot;User not found&amp;quot; }, status: :not_found if user.nil?&lt;br /&gt;
  &lt;br /&gt;
  #   assignment = Assignment.find(assignment_id)&lt;br /&gt;
  #   permissions = participant_permissions(authorization)&lt;br /&gt;
  &lt;br /&gt;
  #   participant = assignment.participants.create(&lt;br /&gt;
  #     user: user,&lt;br /&gt;
  #     handle: handle,&lt;br /&gt;
  #     can_submit: permissions[:can_submit],&lt;br /&gt;
  #     can_review: permissions[:can_review],&lt;br /&gt;
  #     can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
  #     can_mentor: permissions[:can_mentor]&lt;br /&gt;
  #   )&lt;br /&gt;
  &lt;br /&gt;
  #   if participant.persisted?&lt;br /&gt;
  #     render json: participant, status: :created&lt;br /&gt;
  #   else&lt;br /&gt;
  #     render json: { errors: participant.errors.full_messages }, status: :unprocessable_entity&lt;br /&gt;
  #   end&lt;br /&gt;
  # end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) # 👈 You were probably missing this line&lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  #updating authorization of the participants&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def user_params&lt;br /&gt;
    params.require(:user).permit(:name)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def participant_permissions(role)&lt;br /&gt;
    case role&lt;br /&gt;
    when 'Student'&lt;br /&gt;
      { can_submit: true, can_review: false, can_take_quiz: false, can_mentor: false }&lt;br /&gt;
    when 'Reviewer'&lt;br /&gt;
      { can_submit: false, can_review: true, can_take_quiz: false, can_mentor: false }&lt;br /&gt;
    when 'Teaching Assistant'&lt;br /&gt;
      { can_submit: false, can_review: true, can_take_quiz: false, can_mentor: true }&lt;br /&gt;
    when 'Mentor'&lt;br /&gt;
      { can_submit: false, can_review: false, can_take_quiz: false, can_mentor: true }&lt;br /&gt;
    else&lt;br /&gt;
      { can_submit: false, can_review: false, can_take_quiz: false, can_mentor: false }&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_participant&lt;br /&gt;
    @participant = Participant.find(params[:id])&lt;br /&gt;
  rescue ActiveRecord::RecordNotFound&lt;br /&gt;
    render json: { error: &amp;quot;Participant not found&amp;quot; }, status: 404&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def participant_params&lt;br /&gt;
    params.require(:participant).permit(:user_id, :assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  # *****************************************************&lt;br /&gt;
&lt;br /&gt;
  def controller_locale&lt;br /&gt;
    locale_for_student&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # def list&lt;br /&gt;
  #   if Participant::PARTICIPANT_TYPES.include? params[:model]&lt;br /&gt;
  #     @root_node = Object.const_get(params[:model] + 'Node').find_by(node_object_id: params[:id])&lt;br /&gt;
  #     @parent = Object.const_get(params[:model]).find(params[:id])&lt;br /&gt;
  #   end&lt;br /&gt;
  #   begin&lt;br /&gt;
  #     @participants = @parent.participants&lt;br /&gt;
  #     @model = params[:model]&lt;br /&gt;
  #     @authorization = params[:authorization]&lt;br /&gt;
  #   rescue StandardError&lt;br /&gt;
  #     flash[:error] = $ERROR_INFO&lt;br /&gt;
  #   end&lt;br /&gt;
  # end&lt;br /&gt;
&lt;br /&gt;
  # def add&lt;br /&gt;
  #   curr_object = Object.const_get(params[:model]).find(params[:id]) if Participant::PARTICIPANT_TYPES.include? params[:model]&lt;br /&gt;
  #   begin&lt;br /&gt;
  #     permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  #     can_submit = permissions[:can_submit]&lt;br /&gt;
  #     can_review = permissions[:can_review]&lt;br /&gt;
  #     can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
  #     #E2351 - add corresponding duty fill from permissions&lt;br /&gt;
  #     can_mentor = permissions[:can_mentor]&lt;br /&gt;
  #     if curr_object.is_a?(Assignment)&lt;br /&gt;
  #       curr_object.add_participant(params[:user][:name], can_submit, can_review, can_take_quiz, can_mentor)&lt;br /&gt;
  #     elsif curr_object.is_a?(Course)&lt;br /&gt;
  #       curr_object.add_participant(params[:user][:name])&lt;br /&gt;
  #     end&lt;br /&gt;
  #     user = User.find_by(name: params[:user][:name])&lt;br /&gt;
  #     @model = params[:model]&lt;br /&gt;
  #     @participant = curr_object.participants.find_by(user_id: user.id)&lt;br /&gt;
  #     flash.now[:note] = &amp;quot;The user &amp;lt;b&amp;gt;#{params[:user][:name]}&amp;lt;/b&amp;gt; has successfully been added.&amp;quot;&lt;br /&gt;
  #   rescue StandardError&lt;br /&gt;
  #     url_for controller: 'users', action: 'new'&lt;br /&gt;
  #     flash.now[:error] = &amp;quot;The user &amp;lt;b&amp;gt;#{params[:user][:name]}&amp;lt;/b&amp;gt; does not exist or has already been added.&amp;quot;&lt;br /&gt;
  #   end&lt;br /&gt;
  #   render action: 'add.js.erb', layout: false&lt;br /&gt;
  # end&lt;br /&gt;
&lt;br /&gt;
  # when you change the duties, changes the permissions based on the new duty you go to&lt;br /&gt;
  def update_authorizations&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
    can_submit = permissions[:can_submit]&lt;br /&gt;
    can_review = permissions[:can_review]&lt;br /&gt;
    can_take_quiz = permissions[:can_take_quiz]&lt;br /&gt;
    can_mentor = permissions[:can_mentor]&lt;br /&gt;
    parent_id = participant.parent_id&lt;br /&gt;
    # Upon successfully updating the attributes based on user role, a flash message is displayed to the user after the&lt;br /&gt;
    # change in the database. This also gives the user the error message if the update fails.&lt;br /&gt;
    begin&lt;br /&gt;
      participant.update_attributes(can_submit: can_submit, can_review: can_review, can_take_quiz: can_take_quiz, can_mentor: can_mentor)&lt;br /&gt;
      flash[:success] = 'The role of the selected participants has been successfully updated.'&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      flash[:error] = 'The update action failed.'&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: parent_id, model: participant.class.to_s.gsub('Participant', '')&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # def destroy&lt;br /&gt;
  #   participant = Participant.find(params[:id])&lt;br /&gt;
  #   parent_id = participant.parent_id&lt;br /&gt;
  #   begin&lt;br /&gt;
  #     participant.destroy&lt;br /&gt;
  #     flash[:note] = undo_link(&amp;quot;The user \&amp;quot;#{participant.user.name}\&amp;quot; has been successfully removed as a participant.&amp;quot;)&lt;br /&gt;
  #   rescue StandardError&lt;br /&gt;
  #     flash[:error] = 'This participant is on a team, or is assigned as a reviewer for someone’s work.'&lt;br /&gt;
  #   end&lt;br /&gt;
  #   redirect_to action: 'list', id: parent_id, model: participant.class.to_s.gsub('Participant', '')&lt;br /&gt;
  # end&lt;br /&gt;
&lt;br /&gt;
  # Copies existing participants from a course down to an assignment&lt;br /&gt;
  def inherit&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    course = assignment.course&lt;br /&gt;
    @copied_participants = []&lt;br /&gt;
    if course&lt;br /&gt;
      participants = course.participants&lt;br /&gt;
      if !participants.empty?&lt;br /&gt;
        participants.each do |participant|&lt;br /&gt;
          new_participant = participant.copy(params[:id])&lt;br /&gt;
          @copied_participants.push new_participant if new_participant&lt;br /&gt;
        end&lt;br /&gt;
        # Only display undo link if copies of participants are created&lt;br /&gt;
        if !@copied_participants.empty?&lt;br /&gt;
          undo_link(&amp;quot;The participants from \&amp;quot;#{course.name}\&amp;quot; have been successfully copied to this assignment. &amp;quot;)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:note] = 'All course participants are already in this assignment'&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:note] = 'No participants were found to inherit this assignment.'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'No course was found for this assignment.'&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'participants', action: 'list', id: assignment.id, model: 'Assignment'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Take all participants from an assignment and &amp;quot;bequeath&amp;quot; them to course as course_participants.&lt;br /&gt;
  def bequeath_all&lt;br /&gt;
    @copied_participants = []&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    if assignment.course&lt;br /&gt;
      course = assignment.course&lt;br /&gt;
      assignment.participants.each do |participant|&lt;br /&gt;
        new_participant = participant.copy_to_course(course.id)&lt;br /&gt;
        @copied_participants.push new_participant if new_participant&lt;br /&gt;
      end&lt;br /&gt;
      # only display undo link if copies of participants are created&lt;br /&gt;
      if !@copied_participants.empty?&lt;br /&gt;
        undo_link(&amp;quot;All participants were successfully copied to \&amp;quot;#{course.name}\&amp;quot;. &amp;quot;)&lt;br /&gt;
      else&lt;br /&gt;
        flash[:note] = 'All assignment participants are already part of the course'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'This assignment is not associated with a course.'&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'participants', action: 'list', id: assignment.id, model: 'Assignment'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Allow participant to change handle for this assignment&lt;br /&gt;
  # If the participant parameters are available, update the participant&lt;br /&gt;
  # and redirect to the view_actions page&lt;br /&gt;
  def change_handle&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    return unless current_user_id?(@participant.user_id)&lt;br /&gt;
&lt;br /&gt;
    unless params[:participant].nil?&lt;br /&gt;
      if !AssignmentParticipant.where(parent_id: @participant.parent_id, handle: params[:participant][:handle]).empty?&lt;br /&gt;
        ExpertizaLogger.error LoggerMessage.new(controller_name, @participant.name, &amp;quot;Handle #{params[:participant][:handle]} already in use&amp;quot;, request)&lt;br /&gt;
        flash[:error] = &amp;quot;&amp;lt;b&amp;gt;The handle #{params[:participant][:handle]}&amp;lt;/b&amp;gt; is already in use for this assignment. Please select a different one.&amp;quot;&lt;br /&gt;
        redirect_to controller: 'participants', action: 'change_handle', id: @participant&lt;br /&gt;
      else&lt;br /&gt;
        @participant.update_attributes(participant_params)&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, @participant.name, 'The change handle is saved successfully', request)&lt;br /&gt;
        redirect_to controller: 'student_task', action: 'view', id: @participant&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Deletes participants from an assignment&lt;br /&gt;
  def delete&lt;br /&gt;
    contributor = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    name = contributor.name&lt;br /&gt;
    assignment_id = contributor.assignment&lt;br /&gt;
    begin&lt;br /&gt;
        contributor.destroy&lt;br /&gt;
        flash[:note] = &amp;quot;\&amp;quot;#{name}\&amp;quot; is no longer a participant in this assignment.&amp;quot;&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      flash[:error] = &amp;quot;\&amp;quot;#{name}\&amp;quot; was not removed from this assignment. Please ensure that \&amp;quot;#{name}\&amp;quot; is not a reviewer or metareviewer and try again.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    redirect_to controller: 'review_mapping', action: 'list_mappings', id: assignment_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # A ‘copyright grant’ means the author has given permission to the instructor to use the work outside the course.&lt;br /&gt;
  # This is incompletely implemented, but the values in the last column in http://expertiza.ncsu.edu/student_task/list are sourced from here.&lt;br /&gt;
  def view_copyright_grants&lt;br /&gt;
    assignment_id = params[:id]&lt;br /&gt;
    assignment = Assignment.find(assignment_id)&lt;br /&gt;
    @assignment_name = assignment.name&lt;br /&gt;
    @has_topics = false&lt;br /&gt;
    @teams_info = []&lt;br /&gt;
    teams = Team.where(parent_id: assignment_id)&lt;br /&gt;
    teams.each do |team|&lt;br /&gt;
      team_info = {}&lt;br /&gt;
      team_info[:name] = team.name(session[:ip])&lt;br /&gt;
      users = []&lt;br /&gt;
      team.users { |team_user| users.append(get_user_info(team_user, assignment)) }&lt;br /&gt;
      team_info[:users] = users&lt;br /&gt;
      @has_topics = get_signup_topics_for_assignment(assignment_id, team_info, team.id)&lt;br /&gt;
      team_without_topic = SignedUpTeam.where('team_id = ?', team.id).none?&lt;br /&gt;
      next if @has_topics &amp;amp;&amp;amp; team_without_topic&lt;br /&gt;
&lt;br /&gt;
      @teams_info.append(team_info)&lt;br /&gt;
    end&lt;br /&gt;
    @teams_info = @teams_info.sort_by { |hashmap| [hashmap[:topic_id] ? 0 : 1, hashmap[:topic_id] || 0] }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def participant_params&lt;br /&gt;
    params.require(:participant).permit(:can_submit, :can_review, :user_id, :parent_id, :submitted_at,&lt;br /&gt;
                                        :permission_granted, :penalty_accumulated, :grade, :type, :handle,&lt;br /&gt;
                                        :time_stamp, :digital_signature, :can_mentor, :can_take_quiz)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Get the user info from the team user&lt;br /&gt;
  def get_user_info(team_user, assignment)&lt;br /&gt;
    user = {}&lt;br /&gt;
    user[:name] = team_user.name&lt;br /&gt;
    user[:fullname] = team_user.fullname&lt;br /&gt;
    # set by default&lt;br /&gt;
    permission_granted = false&lt;br /&gt;
    assignment.participants.each do |participant|&lt;br /&gt;
      permission_granted = participant.permission_granted? if team_user.id == participant.user.id&lt;br /&gt;
    end&lt;br /&gt;
    # If permission is granted, set the publisting rights string&lt;br /&gt;
    user[:pub_rights] = permission_granted ? 'Granted' : 'Denied'&lt;br /&gt;
    user[:verified] = false&lt;br /&gt;
    user&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Get the signup topics for the assignment&lt;br /&gt;
  def get_signup_topics_for_assignment(assignment_id, team_info, team_id)&lt;br /&gt;
    signup_topics = SignUpTopic.where('assignment_id = ?', assignment_id)&lt;br /&gt;
    if signup_topics.any?&lt;br /&gt;
      has_topics = true&lt;br /&gt;
      signup_topics.each do |signup_topic|&lt;br /&gt;
        signup_topic.signed_up_teams.each do |signed_up_team|&lt;br /&gt;
          if signed_up_team.team_id == team_id&lt;br /&gt;
            team_info[:topic_name] = signup_topic.topic_name&lt;br /&gt;
            team_info[:topic_id] = signup_topic.topic_identifier.to_i&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    has_topics&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
# ***************************************************************************************************&lt;br /&gt;
# class Api::V1::ParticipantsController &amp;lt; ApplicationController&lt;br /&gt;
#   before_action :set_participant, only: [:show, :update, :destroy, :update_authorization]&lt;br /&gt;
&lt;br /&gt;
#   def index&lt;br /&gt;
#     participants = Participant.all&lt;br /&gt;
#     render json: participants, status: :ok&lt;br /&gt;
#   end&lt;br /&gt;
&lt;br /&gt;
#   def show&lt;br /&gt;
#     render json: @participant, status: :ok&lt;br /&gt;
#   end&lt;br /&gt;
&lt;br /&gt;
#   def create&lt;br /&gt;
#     participant = Participant.new(participant_params)&lt;br /&gt;
#     if participant.save&lt;br /&gt;
#       render json: participant, status: :created&lt;br /&gt;
#     else&lt;br /&gt;
#       render json: { errors: participant.errors.full_messages }, status: :unprocessable_entity&lt;br /&gt;
#     end&lt;br /&gt;
#   end&lt;br /&gt;
&lt;br /&gt;
#   def update&lt;br /&gt;
#     if @participant.update(participant_params)&lt;br /&gt;
#       render json: @participant, status: :ok&lt;br /&gt;
#     else&lt;br /&gt;
#       render json: { errors: @participant.errors.full_messages }, status: :unprocessable_entity&lt;br /&gt;
#     end&lt;br /&gt;
#   end&lt;br /&gt;
&lt;br /&gt;
#   def destroy&lt;br /&gt;
#     @participant.destroy&lt;br /&gt;
#     render json: { message: &amp;quot;Participant deleted successfully&amp;quot; }, status: :no_content&lt;br /&gt;
#   end&lt;br /&gt;
&lt;br /&gt;
#   def user_index&lt;br /&gt;
#     participants = Participant.where(user_id: params[:user_id])&lt;br /&gt;
#     render json: participants, status: :ok&lt;br /&gt;
#   end&lt;br /&gt;
&lt;br /&gt;
#   def assignment_index&lt;br /&gt;
#     participants = Participant.where(assignment_id: params[:assignment_id])&lt;br /&gt;
#     render json: participants, status: :ok&lt;br /&gt;
#   end&lt;br /&gt;
&lt;br /&gt;
#   def add&lt;br /&gt;
#     user = User.find_by(name: params[:user][:name])&lt;br /&gt;
#     if user.nil?&lt;br /&gt;
#       render json: { error: &amp;quot;User not found&amp;quot; }, status: :not_found&lt;br /&gt;
#       return&lt;br /&gt;
#     end&lt;br /&gt;
&lt;br /&gt;
#     assignment = Assignment.find(params[:id])&lt;br /&gt;
#     participant = assignment.participants.create(user: user)&lt;br /&gt;
&lt;br /&gt;
#     if participant.persisted?&lt;br /&gt;
#       render json: participant, status: :created&lt;br /&gt;
#     else&lt;br /&gt;
#       render json: { errors: participant.errors.full_messages }, status: :unprocessable_entity&lt;br /&gt;
#     end&lt;br /&gt;
#   end&lt;br /&gt;
&lt;br /&gt;
#   def update_authorization&lt;br /&gt;
#     permissions = participant_permissions(params[:authorization])&lt;br /&gt;
#     if @participant.update(permissions)&lt;br /&gt;
#       render json: @participant, status: :ok&lt;br /&gt;
#     else&lt;br /&gt;
#       render json: { errors: @participant.errors.full_messages }, status: :unprocessable_entity&lt;br /&gt;
#     end&lt;br /&gt;
#   end&lt;br /&gt;
&lt;br /&gt;
#   private&lt;br /&gt;
&lt;br /&gt;
#   def set_participant&lt;br /&gt;
#     @participant = Participant.find_by(id: params[:id])&lt;br /&gt;
#     render json: { error: &amp;quot;Participant not found&amp;quot; }, status: :not_found if @participant.nil?&lt;br /&gt;
#   end&lt;br /&gt;
&lt;br /&gt;
#   def participant_params&lt;br /&gt;
#     params.require(:participant).permit(:user_id, :assignment_id, :can_submit, :can_review, :can_take_quiz)&lt;br /&gt;
#   end&lt;br /&gt;
# end&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya)&lt;br /&gt;
* Brian Huynh (bhhuynh)&lt;br /&gt;
* Akhil Adusumilli (aadusum)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162494</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162494"/>
		<updated>2025-03-24T23:57:49Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Method: add */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) &lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya)&lt;br /&gt;
* Brian Huynh (bhhuynh)&lt;br /&gt;
* Akhil Adusumilli (aadusum)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162493</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162493"/>
		<updated>2025-03-24T23:57:25Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* participants_controller.rb Methods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
 #adding a participant with authorization&lt;br /&gt;
  def add&lt;br /&gt;
    assignment = Assignment.find(params[:id])&lt;br /&gt;
    user = User.find_or_create_by(user_params) # 👈 You were probably missing this line&lt;br /&gt;
  &lt;br /&gt;
    # Now you can safely use `user` below&lt;br /&gt;
    handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant = assignment.participants.create!(&lt;br /&gt;
      user: user,&lt;br /&gt;
      handle: handle,&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :created&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Method: update_authorization ===&lt;br /&gt;
  def update_authorization&lt;br /&gt;
    participant = Participant.find(params[:id])&lt;br /&gt;
  &lt;br /&gt;
    permissions = participant_permissions(params[:authorization])&lt;br /&gt;
  &lt;br /&gt;
    participant.update!(&lt;br /&gt;
      can_submit: permissions[:can_submit],&lt;br /&gt;
      can_review: permissions[:can_review],&lt;br /&gt;
      can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
      can_mentor: permissions[:can_mentor]&lt;br /&gt;
    )&lt;br /&gt;
  &lt;br /&gt;
    render json: participant, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya)&lt;br /&gt;
* Brian Huynh (bhhuynh)&lt;br /&gt;
* Akhil Adusumilli (aadusum)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162492</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162492"/>
		<updated>2025-03-24T23:56:06Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods ==&lt;br /&gt;
The following custom methods were added to handle participant creation with role-based authorization and to update existing participant permissions based on a new authorization.&lt;br /&gt;
&lt;br /&gt;
=== Method: add ===&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
def add&lt;br /&gt;
  assignment = Assignment.find(params[:id])&lt;br /&gt;
  user = User.find_or_create_by(user_params)&lt;br /&gt;
&lt;br /&gt;
  handle = &amp;quot;#{user.name.parameterize}-#{SecureRandom.hex(2)}&amp;quot;&lt;br /&gt;
  permissions = participant_permissions(params[:authorization])&lt;br /&gt;
&lt;br /&gt;
  participant = assignment.participants.create!(&lt;br /&gt;
    user: user,&lt;br /&gt;
    handle: handle,&lt;br /&gt;
    can_submit: permissions[:can_submit],&lt;br /&gt;
    can_review: permissions[:can_review],&lt;br /&gt;
    can_take_quiz: permissions[:can_take_quiz],&lt;br /&gt;
    can_mentor: permissions[:can_mentor]&lt;br /&gt;
  )&lt;br /&gt;
&lt;br /&gt;
  render json: participant, status: :created&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya)&lt;br /&gt;
* Brian Huynh (bhhuynh)&lt;br /&gt;
* Akhil Adusumilli (aadusum)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162489</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162489"/>
		<updated>2025-03-24T23:52:24Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Sample of the Swagger UI API working */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
APIs of all the participants_controller.rb&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya)&lt;br /&gt;
* Brian Huynh (bhhuynh)&lt;br /&gt;
* Akhil Adusumilli (aadusum)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162488</id>
		<title>CSC/ECE 517 Spring 2025 - E2511. Reimplement participants controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2511._Reimplement_participants_controller.rb&amp;diff=162488"/>
		<updated>2025-03-24T23:51:26Z</updated>

		<summary type="html">&lt;p&gt;Vkdodiya: /* Sample of the Swagger UI API working */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
[https://expertiza.github.io Expertiza] is an open source project based on [https://rubyonrails.org Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This project aims to reimplement the &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt; in the new Expertiza system. The &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; manages participants within assignments, and this reimplementation focuses on streamlining its methods, eliminating redundancy, and enhancing code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* Implement &amp;lt;code&amp;gt;participants_controller.rb&amp;lt;/code&amp;gt; Methods: Fully implement each controller method with the same functionality as the current controller.&lt;br /&gt;
* Import from &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;: Integrate relevant helper methods to streamline functionality and remove redundancy.&lt;br /&gt;
* API Creation: Expose API endpoints for all necessary methods to enable seamless access and integration from the frontend. Ensure that each endpoint follows best practices for RESTful API design, including proper error handling and secure data access.&lt;br /&gt;
* Testing with rswag: Create test cases for all methods, focusing on edge cases, and generate rswag documentation.&lt;br /&gt;
* Swagger UI Video Documentation: Record a video walkthrough of API endpoints in Swagger UI, showcasing each method’s functionality.&lt;br /&gt;
&lt;br /&gt;
== Tasks to be Completed ==&lt;br /&gt;
* Implement participants_controller.rb Methods: Develop each method with the same functionality as the existing controller.&lt;br /&gt;
* Refactor and Integrate Helper Methods: Import relevant methods from participants_helper.rb to improve efficiency and eliminate code duplication.&lt;br /&gt;
* API Development: Expose RESTful API endpoints for necessary operations, ensuring proper error handling and secure data access.&lt;br /&gt;
* Testing with Rswag: Implement comprehensive test cases, including edge cases, and generate Rswag documentation.&lt;br /&gt;
* Swagger UI Documentation: Create a video walkthrough demonstrating API endpoints and their functionalities in Swagger UI.&lt;br /&gt;
* Make sure to write intuitive test cases for this controller using RSpec&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Reimplement participants_controller.rb =&lt;br /&gt;
&lt;br /&gt;
== Previous participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| user_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/user/:user_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given user&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| assignment_index&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/assignment/:assignment_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a list of participants for a given assignment&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| show&lt;br /&gt;
| &amp;lt;code&amp;gt;GET /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Return a specified participant&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| add&lt;br /&gt;
| &amp;lt;code&amp;gt;POST /participants/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assign the specified authorization to the participant and add them to an assignment&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| update_authorization&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH /participants/:id/:authorization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Update the specified participant to the specified authorization&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| destroy&lt;br /&gt;
| &amp;lt;code&amp;gt;DELETE /participants/:id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| participant_params&lt;br /&gt;
| -&lt;br /&gt;
| Permitted parameters for creating a Participant object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== participants_controller.rb Methods / API Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! #&lt;br /&gt;
! HTTP Method&lt;br /&gt;
! Endpoint&lt;br /&gt;
! Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| index&lt;br /&gt;
| List all participants&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants&lt;br /&gt;
| create&lt;br /&gt;
| Create a new participant&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| show&lt;br /&gt;
| Retrieve a participant by ID&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| PUT&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| update&lt;br /&gt;
| Update a participant&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| DELETE&lt;br /&gt;
| /api/v1/participants/:id&lt;br /&gt;
| destroy&lt;br /&gt;
| Delete a participant&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/user/:user_id&lt;br /&gt;
| user_index&lt;br /&gt;
| Get participants by user ID&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| GET&lt;br /&gt;
| /api/v1/participants/assignment/:assignment_id&lt;br /&gt;
| assignment_index&lt;br /&gt;
| Get participants by assignment ID&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| POST&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| add&lt;br /&gt;
| Add a participant with authorization&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PATCH&lt;br /&gt;
| /api/v1/participants/:id/:authorization&lt;br /&gt;
| update_authorization&lt;br /&gt;
| Update participant authorization&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Removed Methods from participants_controller.rb ==&lt;br /&gt;
&lt;br /&gt;
The following methods were removed as part of the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;action_allowed?&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;controller_locale&amp;lt;/code&amp;gt; – No impact on functionality.&lt;br /&gt;
* &amp;lt;code&amp;gt;inherit&amp;lt;/code&amp;gt; – Redundant due to lack of direct relation between Course and Participant.&lt;br /&gt;
* &amp;lt;code&amp;gt;bequeath_all&amp;lt;/code&amp;gt; – Same reason as above.&lt;br /&gt;
* &amp;lt;code&amp;gt;change_handle&amp;lt;/code&amp;gt; – `User` model already has `handle`, so it's redundant.&lt;br /&gt;
* &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; – Replaced by `remove_participant` in &amp;lt;code&amp;gt;assignments_controller.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;view_copyright_grants&amp;lt;/code&amp;gt; – Old implementation was incorrect.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_user_info&amp;lt;/code&amp;gt; – Covered by `belongs_to` relation in the `Participant` model.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_signup_topics_for_assignment&amp;lt;/code&amp;gt; – Now handled by `sign_up_topics_controller.rb`.&lt;br /&gt;
&lt;br /&gt;
== Implementation Summary ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Api::V1::ParticipantsController&amp;lt;/code&amp;gt; was restructured to:&lt;br /&gt;
* Follow RESTful conventions (`index`, `show`, `create`, `update`, `destroy`)&lt;br /&gt;
* Add custom endpoints for `user_index`, `assignment_index`, and `update_authorization`&lt;br /&gt;
* Leverage strong parameters and `before_action` filters&lt;br /&gt;
* Integrate logic from `participants_helper.rb` (like `participant_permissions`)&lt;br /&gt;
* Improve error handling using status codes and JSON messages&lt;br /&gt;
&lt;br /&gt;
== participants_helper.rb Methods ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ParticipantsHelper&amp;lt;/code&amp;gt; module contains utility methods used to assign roles and permissions to a Participant. Compared to the original implementation, this version has been heavily simplified and cleaned up.&lt;br /&gt;
&lt;br /&gt;
Only the following method is included in the reimplementation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;retrieve_participant_permissions&amp;lt;/code&amp;gt; – Returns a hash of permission flags based on the participant’s assigned role.&lt;br /&gt;
  This method sets default permissions (submit, review, quiz, mentor) and overrides them based on the role passed in. The supported roles are:&lt;br /&gt;
  * &amp;lt;code&amp;gt;reader&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;reviewer&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;submitter&amp;lt;/code&amp;gt;&lt;br /&gt;
  * &amp;lt;code&amp;gt;mentor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ```ruby&lt;br /&gt;
  def retrieve_participant_permissions(authorization)&lt;br /&gt;
    default_permissions = {&lt;br /&gt;
      can_submit: true,&lt;br /&gt;
      can_review: true,&lt;br /&gt;
      can_take_quiz: true,&lt;br /&gt;
      can_mentor: false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    permissions_map = {&lt;br /&gt;
      'reader' =&amp;gt; { can_submit: false },&lt;br /&gt;
      'reviewer' =&amp;gt; { can_submit: false, can_take_quiz: false },&lt;br /&gt;
      'submitter' =&amp;gt; { can_review: false, can_take_quiz: false },&lt;br /&gt;
      'mentor' =&amp;gt; { can_mentor: true }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default_permissions.merge(permissions_map[authorization])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== Role-Based Strategy Pattern ==&lt;br /&gt;
&lt;br /&gt;
As part of this reimplementation, a Strategy Design Pattern was introduced to streamline role-based permission handling, replacing the large conditional structure previously present in &amp;lt;code&amp;gt;participants_helper.rb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This pattern allows each role to encapsulate its own permission logic, enabling easier testing, extension, and adherence to SOLID principles.&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
The strategy pattern consists of the following components located under the &amp;lt;code&amp;gt;Strategies/roles&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mentor_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reviewer_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;student_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;teacher_assistant_strategy.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;role_strategy.rb&amp;lt;/code&amp;gt; – Base module defining required methods&lt;br /&gt;
* &amp;lt;code&amp;gt;role_context.rb&amp;lt;/code&amp;gt; – Context class that uses strategies dynamically&lt;br /&gt;
&lt;br /&gt;
=== How it Works ===&lt;br /&gt;
&lt;br /&gt;
Each role strategy implements the &amp;lt;code&amp;gt;get_permissions&amp;lt;/code&amp;gt; method to return a role-specific permission hash, for example:&lt;br /&gt;
&lt;br /&gt;
```ruby&lt;br /&gt;
# Example from MentorStrategy&lt;br /&gt;
&amp;lt;code&amp;gt;def get_permissions&amp;lt;/code&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    can_submit: false,&lt;br /&gt;
    can_review: false,&lt;br /&gt;
    can_take_quiz: false,&lt;br /&gt;
    can_mentor: true&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sample of the Swagger UI API working ==&lt;br /&gt;
&lt;br /&gt;
[[File:participants_API.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Updating a user by specific id&lt;br /&gt;
[[File:Updating_participant_ss1.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
Request successful with User updated&lt;br /&gt;
[[File:Updating_participant_ss2.png |center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* [https://github.com/expertiza/expertiza Expertiza GitHub Repository]&lt;br /&gt;
* [https://guides.rubyonrails.org/routing.html Rails Routing Guide]&lt;br /&gt;
* [https://rswag.org rswag API Documentation Tool]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
* Vansh Dodiya (vkdodiya)&lt;br /&gt;
* Brian Huynh (bhhuynh)&lt;br /&gt;
* Akhil Adusumilli (aadusum)&lt;br /&gt;
&lt;br /&gt;
== Mentor ==&lt;br /&gt;
* Aniruddha Rajnekar&lt;/div&gt;</summary>
		<author><name>Vkdodiya</name></author>
	</entry>
</feed>