<?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=Mtmiddle</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=Mtmiddle"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Mtmiddle"/>
	<updated>2026-05-10T17:04:39Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=159934</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=159934"/>
		<updated>2024-12-01T21:06:28Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: /* E2470. Reimplement grades controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/138 Link to Factory Changes (Does not include participant scores model)]===&lt;br /&gt;
&lt;br /&gt;
===[https://drive.google.com/file/d/1lgFLevdhs7PTFpibxflQfB45nOXW04jA/view?usp=sharing Swagger Video Submission]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents. Additionally, we will be testing the controller with rswag.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor grade_controller.rb, which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
API::V1::GradesController utilizes action-based permissions through action_allowed to provide broader functionality to instructors versus students. With the frontend systems of the Grades Controller relying on heat map systems, view and view_team provide the detailed grading information to populate them (from the student perspective, reviewer identities are kept hidden). The edit method retrieves the relevant assignment to be modified by the frontend view. For accessing reviews, instructor_review is utilized, leading to access of previous reviews or instantiating new ones. Finally, grade changes are saved through the update function, which additionally covers comment feedback.&lt;br /&gt;
&lt;br /&gt;
This controller structure aligns closely with the traditional CRUD operations providing an organized way to handle grade management. The view and view_team actions are for the Read functionality, allowing both instructors and students to access and review grade data based on their roles. The Create aspect is handled in instructor_review, which either retrieves existing reviews or initiates new ones as needed, ensuring that instructors can easily add comments or feedback for an assignment.&lt;br /&gt;
&lt;br /&gt;
The Update action is fulfilled by update, which is responsible for saving new grading data and feedback from instructors. The Delete functionality is not something the grades_controller is responsible for handling.&lt;br /&gt;
&lt;br /&gt;
This CRUD focused approach makes sure that the refactored grade_controller.rb is efficient and easily maintainable, while offering both instructors and students a seamless experience in managing and reviewing assignment grades. The refactor further enhances clarity and accessibility, aiming to make each action intuitive and easily accessible to the relevant users within Expertiza.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's point of view, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's point of view which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's point of view&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
===Rationale for Changes===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
|-&lt;br /&gt;
|Added a new suite of API endpoint tests that are compatible with Rswag and tested our API endpoints thoroughly, additionally added factories for several projects in the system.&lt;br /&gt;
|As with any software change in a large system, testing is extremely important, so we wrote comprehensive tests for our endpoints.  Additionally, since the grades_controller is dependent on many other models (mainly because there is no grades model).  These changes will help future projects by providing factory methods for various models that did not currently have them in the system which should make testing for other groups easier in the future.&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Code Snippet===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Determines if the current user is able to perform :action as specified by the path parameter&lt;br /&gt;
  # If the user has the role of TA or higher they are granted access to all operations beyond view_team&lt;br /&gt;
  # Uses a switch statement for easy maintainability if added functionality is ever needed for students or&lt;br /&gt;
  # additional roles, to add more functionality simply add additional switch cases in the same syntax with&lt;br /&gt;
  # case 'action' and then some boolean check determining if that is allowed or forbidden.&lt;br /&gt;
  # GET /api/v1/grades/:action/action_allowed&lt;br /&gt;
  def action_allowed&lt;br /&gt;
    permitted = case params[:action]&lt;br /&gt;
                when 'view_team'&lt;br /&gt;
                  view_team_allowed?&lt;br /&gt;
                else&lt;br /&gt;
                  user_ta_privileges?&lt;br /&gt;
                end&lt;br /&gt;
    render json: { allowed: permitted }, status: permitted ? :ok : :forbidden&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides the needed functionality of querying needed values from the backend db and returning them to build the&lt;br /&gt;
  # heat map in the frontend from the TA/staff view.  These values are set in the get_data_for_heat_map method&lt;br /&gt;
  # which takes the assignment id as a parameter.&lt;br /&gt;
  # GET /api/v1/grades/:id/view&lt;br /&gt;
  def view&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    render json: { scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                   review_score_count: @review_score_count }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides all relevant data for the student perspective for the heat map page as well as the&lt;br /&gt;
  # needed information to showcase the questionnaires from the student view.  Additionally, handles the removal of user&lt;br /&gt;
  # identification in the reviews within the hide_reviewers_rom_student method.&lt;br /&gt;
  # GET /api/v1/grades/:id/view_team&lt;br /&gt;
  def view_team&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    @scores[:participants] = hide_reviewers_from_student&lt;br /&gt;
    questionnaires = @assignment.questionnaires&lt;br /&gt;
    questions = retrieve_questions(questionnaires, @assignment.id)&lt;br /&gt;
    render json: {scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                  review_score_count: @review_score_count, questions: questions }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Sets information required for editing the grade information, this includes the participant, questions, scores, and&lt;br /&gt;
  # assignment&lt;br /&gt;
  # GET /api/v1/grades/:id/edit&lt;br /&gt;
  def edit&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: {message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot;}, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    questions = list_questions(assignment)&lt;br /&gt;
    scores = review_grades(assignment, questions)&lt;br /&gt;
    render json: {participant: participant, questions: questions, scores: scores, assignment: assignment}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides functionality that handles informing the frontend which controller and action to direct to for instructor&lt;br /&gt;
  # review given the current state of the system.  The intended controller to handle the creation or editing of a review&lt;br /&gt;
  # is the response controller, however this method just determines if a new review must be made based on figuring out&lt;br /&gt;
  # whether or not an associated review_mapping exists from the participant already.  If one does they should go to&lt;br /&gt;
  # Response#edit and if one does not they should go to Response#new.  Only ever returns a status of ok.&lt;br /&gt;
  # GET /api/v1/grades/:id/instructor_review&lt;br /&gt;
  def instructor_review&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: { message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot; }, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    review_mapping = find_participant_review_mapping(participant)&lt;br /&gt;
    if review_mapping.new_record?&lt;br /&gt;
      render json: { controller: 'response', action: 'new', id: review_mapping.map_id,&lt;br /&gt;
                     return: 'instructor'}, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      review = Response.find_by(map_id: review_mapping.map_id)&lt;br /&gt;
      render json: { controller: 'response', action: 'edit', id: review.id, return: 'instructor'}, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Update method for the grade associated with a team, allows an instructor to upgrade a team's grade with a grade&lt;br /&gt;
  # and a comment on their assignment for submission.  The team is then saved with this change in order to be accessed&lt;br /&gt;
  # elsewhere in the code for needed scoring evaluations.  If a failure occurs while saving the team then this will&lt;br /&gt;
  # return a bad_request response complete with a message and the global ERROR_INFO which can be set elsewhere for&lt;br /&gt;
  # further error handling mechanisms&lt;br /&gt;
  # PATCH /api/v1/grades/:participant_id/update/:grade_for_submission&lt;br /&gt;
  def update&lt;br /&gt;
    participant = AssignmentParticipant.find_by(id: params[:participant_id])&lt;br /&gt;
&lt;br /&gt;
    team = participant.team&lt;br /&gt;
    team.grade_for_submission = params[:grade_for_submission]&lt;br /&gt;
    team.comment_for_submission = params[:comment_for_submission]&lt;br /&gt;
    begin&lt;br /&gt;
      team.save&lt;br /&gt;
    rescue StandardError =&amp;gt; e&lt;br /&gt;
      render json: {message: &amp;quot;Error occurred while updating grade for team #{team.id}&amp;quot;,&lt;br /&gt;
                    error: e.message }, status: :bad_request&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: { controller: 'grades', action: 'view_team', id: participant.id}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===CRUD functionality===&lt;br /&gt;
Before we did our refactor and reimplementation the grades_controller contained several unnecessary methods as well as functions vastly beyond the CRUD operations that belong within a controller like this.  The two CRUD operations that are presently in the system for the grades_controller are read and updated.  The read operation is implemented within the view and view_team method to provide the needed information to view the grade heat map.  Then the update functionality is primarily implemented in the needed edit method which supplies information before the update and the update method has been vastly modified from its old implementation where it was not actually saving objects, we have replaced that with a proper update that modifies the grade and comment similarly to how the old save_grade_and_comment_for_submission method used to work.&lt;br /&gt;
===SOLID Principles===&lt;br /&gt;
Overall we strove to meet SOLID guidelines by limiting the scope of the controller back down to its intended core functionality.  This helped satisfy the single responsibility principle by removing additional functionality beyond the intended scope of this class.  We have also significantly cut down on the required helpers needed for these operations through our implementation of a new model participant_scores which helps serve the singular goal of keeping track of score information for questions on an assignment for a given participant. We have also improved the maintainability of the code by making our methods more atomic which should promote extension outside of our methods for new functionality satisfying the Open/Close principle. The remaining three principles did not really apply to this project as the grades_controller has minimal interactions with it's superclass and has no independent model that it controls or is responsible for governing.&lt;br /&gt;
===DRY principle===&lt;br /&gt;
To satisfy the don't repeat yourself principle we sought to make private helper methods to abstract repeated code that was adding complexity to our methods.  One such method is the get_data_for_heat_map method which replaces a substantial amount of what used to be complex and repeated code, which has now been significantly simplified for readability.  Please see the snippet below for the new method, it's primary goal is to set the instance variables of the controller as needed so we can prepare data for the heat map as needed in the front end.  We also relocated complex code that did not aid in the readability into helper methods which have also been refactored, the main goal of this was to promote readability in the main endpoint methods remove unnecessary clutter from the code, and limit code repetition in future modifications by providing modular helper methods for functionality that we believe may need to be repeated in future enhancements such as listing the questions or querying review grades.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Provides data for the heat maps in the view statements&lt;br /&gt;
  def get_data_for_heat_map(id)&lt;br /&gt;
    # Finds the assignment&lt;br /&gt;
    @assignment = Assignment.find(id)&lt;br /&gt;
    # Extracts the questionnaires&lt;br /&gt;
    @questions = filter_questionnaires(@assignment)&lt;br /&gt;
    @scores = review_grades(@assignment, @questions)&lt;br /&gt;
    @review_score_count = @scores[:teams].length # After rejecting nil scores need original length to iterate over hash&lt;br /&gt;
    @averages = vector(@scores)&lt;br /&gt;
    @avg_of_avg = mean(@averages)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Testing Details===&lt;br /&gt;
The test file can be located at:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spec/requests/api/v1/grades_controller_spec.rb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''action_allowed'''&lt;br /&gt;
** Passes in the view action and an assignment we wish to view. Determines if the user has the appropriate permissions to view it.&lt;br /&gt;
*'''view'''&lt;br /&gt;
** Passes in the id of the assignment and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''view_team'''&lt;br /&gt;
** Pasess in the assignment id and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''edit'''&lt;br /&gt;
** Passes in the id of the assignment and expects the participant's id, the same assignment's id, '''questions''', and '''scores'''.&lt;br /&gt;
*'''instructor_review'''&lt;br /&gt;
** Passes in the id of a participant and expects '''controller''', '''action''', the same participant id, and the instructor.&lt;br /&gt;
*'''update'''&lt;br /&gt;
** Passes in a participant id and a body which contains '''grade_for_submission''' (integer) and '''comment_for_submission''' (string). Expects the same grade, comment, '''action''', and participant's id.&lt;br /&gt;
&lt;br /&gt;
'''Rswag UI'''&lt;br /&gt;
[[File:Grades_controller_test_fall_2024.png|700px|An image showing the rswag ui of accepted test results.]]&lt;br /&gt;
&lt;br /&gt;
=Final project additions=&lt;br /&gt;
==The Problem and Remaining Work==&lt;br /&gt;
While working on our OSS project we ran into substantial difficulties with testing our controller.  The primary reason for this is that the grades_controller is one of the first controller classes in the reimplementation backend that does not have a primary model associated with it.  This is because it does not seem prudent to make a grades model, as scores can be held and tracked as fields in other objects as primitives so this abstraction would not be particularly helpful.  However, this poses an interesting challenge when testing and reimplementing the controller.  Specifically, the dependency on the successful initialization of numerous models throughout the controller including Assignment, Participant, and Team to name a few of the model classes required for operations within the grades_controller for the present create and edit CRUD operations implemented within.  During our OSS project, we were able to slim down the controller and implement more elegant and atomic solutions to the tasks that the original controller was responsible for with some refactoring and reimplementation of various methods.  However, even with these changes, the grades_controller is still dependent on several other classes and their interactions within the system being initialized and in a valid state in order to perform (or test) the required operations.&lt;br /&gt;
&lt;br /&gt;
The primary difficulty in testing our controller as indicated above was this high dependency on other models for correct functionality.  Because of this, we had to construct and instantiate several different models in our test code.  This, in a vacuum, may not be an issue.  However, as the reimplementation backend codebase continues to grow this issue has the potential to become a recurring one where the ultimate result will be several violations of the DRY principle in the testing suite instantiating needed objects inside of controller tests similarly to the way that we had to do this at the start.  In the current codebase, the only models containing factory code are student_task, join_team_request, bookmark, and user, making this substantially shy of the thirty-six models currently residing within the reimplementation_backend repository.  We will seek to change this in order to limit the likelihood of DRY violations in the test suite moving forward to improve code maintainability and consistency.  This should also directly benefit future students who will not need to struggle with implementing testing for dependent controllers.  It should also make future refactors much less painful in terms of changing models breaking test cases, if the models are built in factories these issues may be rectified for all failing locations within the factory class rather than requiring the modification of several test files in the system.&lt;br /&gt;
&lt;br /&gt;
==Our solution==&lt;br /&gt;
Our solution to improving our OSS submission and the overall codebase is four-pronged.  This includes expanding the factory suite to include many additional models.  Our second plan is to improve our test cases and our overall test plan to be more comprehensive of all branches present in our code to conduct more thorough testing using our new factories.  Our third change will be to modify the seeding files for the db in order to facilitate manual testing with RSwag.  Finally our fourth goal for the project is to improve our RSwag UI by implementing the previous three steps and then ensuring that manual testing capability is achieved and correct.&lt;br /&gt;
===Expanded Factory Suite===&lt;br /&gt;
For our final project we are seeking to improve the code base by expanding the factory suite to include factories for most of the 37 models present in the reimplementation backend repository. The rationale behind this decision is to improve the testing capabilities of all controllers either currently in the system or ones that will be added. As the code base grows, we expect an increased interdependency of the controllers on the model classes. Without factory classes, this would result in an opportunity for several DRY violations in the test suite. This hinders the maintainability of the code base and as small changes in the models could break the entire test suite and would need to be solved individually in every test case; however, with factories, we would only need to fix the code within the factories to reflect the new code structure and the test cases will remain largely unchanged. We would also suggest that factories be continuously updated as new models are added so that it aids in future maintainability.&lt;br /&gt;
&lt;br /&gt;
===Improved Test Plan===&lt;br /&gt;
* action_allowed&lt;br /&gt;
** If the user is a TA or higher, then a successful status will be returned for all actions.&lt;br /&gt;
** If the user is a student and requests to view their team then, then a successful status will be returned.&lt;br /&gt;
** Otherwise, a status of prohibited is rendered regardless of the action.&lt;br /&gt;
* view&lt;br /&gt;
** A successful status, the scores, the assignment, the averages, the meta average, and the review score count are all rendered so that the heat map can be displayed. &lt;br /&gt;
* view_team&lt;br /&gt;
** A successful status, the scores, the assignment with filtered questionnaire authors , the averages, the meta average, and the review score count are all rendered so that the heat map can be displayed. &lt;br /&gt;
* edit&lt;br /&gt;
** If the assignment participant is not found, then a not found status is rendered.&lt;br /&gt;
** Otherwise, a successful status, the participant, the questions, the scores, and the assignment are all rendered.&lt;br /&gt;
* instructor_review&lt;br /&gt;
** If the assignment participant is not found, then a not found status is rendered.&lt;br /&gt;
** If the instructor review is new then a response is rendered to tell the front end to go to the response controllers new action with the reviews mapping's id.&lt;br /&gt;
** Otherwise, a response is rendered to tell the front end to go to the response controller's edit action with the review's id.&lt;br /&gt;
* update&lt;br /&gt;
** If the team cannot be saved, then a bad request status is rendered.&lt;br /&gt;
** Otherwise, a response is rendered to tell the front end to go to the grades controller's view team action with the participant's id.&lt;br /&gt;
====Flow Chart====&lt;br /&gt;
[[File:Decision_tree.png|700px|An image showing flow chart]]&lt;br /&gt;
&lt;br /&gt;
===Modified db seeding===&lt;br /&gt;
Currently the file '''seeds.rb''' contains only an institution and admin user. To streamline testing and set up appropriate models, we will make sure the file contains the following:&lt;br /&gt;
* An assignment instance&lt;br /&gt;
* A participant instance&lt;br /&gt;
* A team instance&lt;br /&gt;
* An instructor instance&lt;br /&gt;
To perform testing for the API endpoints, these are the minimum model instances required. The goal of this change is to make sure we can handle manually testing the grades controller with the rswag UI. This is specifically for the reimplementation of the backend. There is an absence of several necessary POST API endpoints implementing CREATE operations. Without these seeded into the database, we would need to cover more implementation on endpoints.&lt;br /&gt;
&lt;br /&gt;
===Functional RSwagUI visualizations and manual testing capability===&lt;br /&gt;
Currently, we have the endpoint visualizations set up on RSwag's UI, and just need to complete the previous steps for visualized results.  This will also ensure that our API endpoints are fully compatible with manual testing in the UI which is beneficial for various reasons.  Including testing new edge cases as they come up or the code expands before even making a unit test for simple things (although in the future for maintainability if a new edge case is discovered it should be added to the test suite).  This will allow future students to test our endpoints using the UI, and we imagine this will be particularly helpful for the future teams working on the frontend as they will be able to manually run their API requests and see the JSON response they are getting in one window to manually check their frontend calls.  This should help speed up their debugging process or clear up any uncertainty in behavior beyond the current code documentation if any remains.&lt;br /&gt;
&lt;br /&gt;
===Grades Controller Changes (Improvements based on OSS Project Feedback)===&lt;br /&gt;
* We reduced the complexity of the scores data structure. We started with a quadruple-layered hash map and reduced it to a simple hash map with two branches. This was facilitated &lt;br /&gt;
through the participants' scores model.&lt;br /&gt;
* The complexity fixes were primarily done through modifying '''review_grades'''.&lt;br /&gt;
** Instead of handling '''scores[:teams][team_id][:scores][:avg]''', we changed it to be '''scores[:teams][team_id]'''.&lt;br /&gt;
'''Before:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
team_id = team.id.to_s.to_sym&lt;br /&gt;
      scores[:teams][team_id] ||= { scores: { avg: 0 } }&lt;br /&gt;
&lt;br /&gt;
      # Calculate average score for the team&lt;br /&gt;
      team_scores = participant_scores.map { |s| s[:score].to_f / s[:total_score] * 100 }&lt;br /&gt;
      scores[:teams][team_id][:scores][:avg] = team_scores.sum / team_scores.size&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''After:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
scores[:teams][team_id] ||= 0&lt;br /&gt;
&lt;br /&gt;
      # Calculate average score for the team&lt;br /&gt;
      team_scores = participant_scores.map { |s| s[:score].to_f / s[:total_score] * 100 }&lt;br /&gt;
      scores[:teams][team_id] = team_scores.sum / team_scores.size&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* We changed the logic for '''vector'''&lt;br /&gt;
** We renamed it to: '''filter_scores'''&lt;br /&gt;
** Thanks to the simplification of the scores data structure, the function no longer violates the '''DRY Principle''' and is more readable.&lt;br /&gt;
'''Before:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    scores[:teams].reject! { |_k, v| v[:scores][:avg].nil? }&lt;br /&gt;
    scores[:teams].map { |_k, v| v[:scores][:avg].to_i }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''After:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    team_scores&lt;br /&gt;
      .compact&lt;br /&gt;
      .map { |team| team.is_a?(Array) ? team[1].to_i : team.to_i }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* We updated the documentation for '''edit''' and '''instructor_review''' in order to make it clear what the functions accomplished, why, and how.&lt;br /&gt;
* We changed the JSON rendering for '''view_team''' and '''view'''. They were previously returning duplicate data within our scores data structure. Since the modification, it is only returning labeled data that is easily accessible without manipulating the hash.&lt;br /&gt;
* We modified the internal data structure usage, only passing the participants or team branch of the scores data structure, instead of passing the previous structure around.&lt;br /&gt;
&lt;br /&gt;
===Future Implementation===&lt;br /&gt;
* The grades controller still has dependencies with other controllers modifying values used by this class, that will be reimplemented in the future. Specifically, the participant's scores model needs to be populated in the response controller when it is reimplemented in the future. &lt;br /&gt;
* Additionally, any future views requiring heatmap support will be able to utilize our private helper methods that were designed to be flexible in the grades controller with consistent data filtering. Additional filters will need to be added as separate code, rather than modifying ours to follow the open/closed principle.&lt;br /&gt;
* The professor instructed us to use the old authorization helper file, which is fine for this work in progress system. However, this file will need to be updated in the future internally to reflect the changes to web token-based authentication. Presently, the helper file assumes we use session-based authentication in the back end which is no longer the case. However, it's important to note this still works in the testing environment.&lt;br /&gt;
&lt;br /&gt;
=Team and Prior information=&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;br /&gt;
&lt;br /&gt;
==Previous Iterations==&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=159933</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=159933"/>
		<updated>2024-12-01T20:59:42Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: /* Future Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
===[https://drive.google.com/file/d/1lgFLevdhs7PTFpibxflQfB45nOXW04jA/view?usp=sharing Swagger Video Submission]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents. Additionally, we will be testing the controller with rswag.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor grade_controller.rb, which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
API::V1::GradesController utilizes action-based permissions through action_allowed to provide broader functionality to instructors versus students. With the frontend systems of the Grades Controller relying on heat map systems, view and view_team provide the detailed grading information to populate them (from the student perspective, reviewer identities are kept hidden). The edit method retrieves the relevant assignment to be modified by the frontend view. For accessing reviews, instructor_review is utilized, leading to access of previous reviews or instantiating new ones. Finally, grade changes are saved through the update function, which additionally covers comment feedback.&lt;br /&gt;
&lt;br /&gt;
This controller structure aligns closely with the traditional CRUD operations providing an organized way to handle grade management. The view and view_team actions are for the Read functionality, allowing both instructors and students to access and review grade data based on their roles. The Create aspect is handled in instructor_review, which either retrieves existing reviews or initiates new ones as needed, ensuring that instructors can easily add comments or feedback for an assignment.&lt;br /&gt;
&lt;br /&gt;
The Update action is fulfilled by update, which is responsible for saving new grading data and feedback from instructors. The Delete functionality is not something the grades_controller is responsible for handling.&lt;br /&gt;
&lt;br /&gt;
This CRUD focused approach makes sure that the refactored grade_controller.rb is efficient and easily maintainable, while offering both instructors and students a seamless experience in managing and reviewing assignment grades. The refactor further enhances clarity and accessibility, aiming to make each action intuitive and easily accessible to the relevant users within Expertiza.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's point of view, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's point of view which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's point of view&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
===Rationale for Changes===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
|-&lt;br /&gt;
|Added a new suite of API endpoint tests that are compatible with Rswag and tested our API endpoints thoroughly, additionally added factories for several projects in the system.&lt;br /&gt;
|As with any software change in a large system, testing is extremely important, so we wrote comprehensive tests for our endpoints.  Additionally, since the grades_controller is dependent on many other models (mainly because there is no grades model).  These changes will help future projects by providing factory methods for various models that did not currently have them in the system which should make testing for other groups easier in the future.&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Code Snippet===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Determines if the current user is able to perform :action as specified by the path parameter&lt;br /&gt;
  # If the user has the role of TA or higher they are granted access to all operations beyond view_team&lt;br /&gt;
  # Uses a switch statement for easy maintainability if added functionality is ever needed for students or&lt;br /&gt;
  # additional roles, to add more functionality simply add additional switch cases in the same syntax with&lt;br /&gt;
  # case 'action' and then some boolean check determining if that is allowed or forbidden.&lt;br /&gt;
  # GET /api/v1/grades/:action/action_allowed&lt;br /&gt;
  def action_allowed&lt;br /&gt;
    permitted = case params[:action]&lt;br /&gt;
                when 'view_team'&lt;br /&gt;
                  view_team_allowed?&lt;br /&gt;
                else&lt;br /&gt;
                  user_ta_privileges?&lt;br /&gt;
                end&lt;br /&gt;
    render json: { allowed: permitted }, status: permitted ? :ok : :forbidden&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides the needed functionality of querying needed values from the backend db and returning them to build the&lt;br /&gt;
  # heat map in the frontend from the TA/staff view.  These values are set in the get_data_for_heat_map method&lt;br /&gt;
  # which takes the assignment id as a parameter.&lt;br /&gt;
  # GET /api/v1/grades/:id/view&lt;br /&gt;
  def view&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    render json: { scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                   review_score_count: @review_score_count }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides all relevant data for the student perspective for the heat map page as well as the&lt;br /&gt;
  # needed information to showcase the questionnaires from the student view.  Additionally, handles the removal of user&lt;br /&gt;
  # identification in the reviews within the hide_reviewers_rom_student method.&lt;br /&gt;
  # GET /api/v1/grades/:id/view_team&lt;br /&gt;
  def view_team&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    @scores[:participants] = hide_reviewers_from_student&lt;br /&gt;
    questionnaires = @assignment.questionnaires&lt;br /&gt;
    questions = retrieve_questions(questionnaires, @assignment.id)&lt;br /&gt;
    render json: {scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                  review_score_count: @review_score_count, questions: questions }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Sets information required for editing the grade information, this includes the participant, questions, scores, and&lt;br /&gt;
  # assignment&lt;br /&gt;
  # GET /api/v1/grades/:id/edit&lt;br /&gt;
  def edit&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: {message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot;}, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    questions = list_questions(assignment)&lt;br /&gt;
    scores = review_grades(assignment, questions)&lt;br /&gt;
    render json: {participant: participant, questions: questions, scores: scores, assignment: assignment}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides functionality that handles informing the frontend which controller and action to direct to for instructor&lt;br /&gt;
  # review given the current state of the system.  The intended controller to handle the creation or editing of a review&lt;br /&gt;
  # is the response controller, however this method just determines if a new review must be made based on figuring out&lt;br /&gt;
  # whether or not an associated review_mapping exists from the participant already.  If one does they should go to&lt;br /&gt;
  # Response#edit and if one does not they should go to Response#new.  Only ever returns a status of ok.&lt;br /&gt;
  # GET /api/v1/grades/:id/instructor_review&lt;br /&gt;
  def instructor_review&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: { message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot; }, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    review_mapping = find_participant_review_mapping(participant)&lt;br /&gt;
    if review_mapping.new_record?&lt;br /&gt;
      render json: { controller: 'response', action: 'new', id: review_mapping.map_id,&lt;br /&gt;
                     return: 'instructor'}, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      review = Response.find_by(map_id: review_mapping.map_id)&lt;br /&gt;
      render json: { controller: 'response', action: 'edit', id: review.id, return: 'instructor'}, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Update method for the grade associated with a team, allows an instructor to upgrade a team's grade with a grade&lt;br /&gt;
  # and a comment on their assignment for submission.  The team is then saved with this change in order to be accessed&lt;br /&gt;
  # elsewhere in the code for needed scoring evaluations.  If a failure occurs while saving the team then this will&lt;br /&gt;
  # return a bad_request response complete with a message and the global ERROR_INFO which can be set elsewhere for&lt;br /&gt;
  # further error handling mechanisms&lt;br /&gt;
  # PATCH /api/v1/grades/:participant_id/update/:grade_for_submission&lt;br /&gt;
  def update&lt;br /&gt;
    participant = AssignmentParticipant.find_by(id: params[:participant_id])&lt;br /&gt;
&lt;br /&gt;
    team = participant.team&lt;br /&gt;
    team.grade_for_submission = params[:grade_for_submission]&lt;br /&gt;
    team.comment_for_submission = params[:comment_for_submission]&lt;br /&gt;
    begin&lt;br /&gt;
      team.save&lt;br /&gt;
    rescue StandardError =&amp;gt; e&lt;br /&gt;
      render json: {message: &amp;quot;Error occurred while updating grade for team #{team.id}&amp;quot;,&lt;br /&gt;
                    error: e.message }, status: :bad_request&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: { controller: 'grades', action: 'view_team', id: participant.id}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===CRUD functionality===&lt;br /&gt;
Before we did our refactor and reimplementation the grades_controller contained several unnecessary methods as well as functions vastly beyond the CRUD operations that belong within a controller like this.  The two CRUD operations that are presently in the system for the grades_controller are read and updated.  The read operation is implemented within the view and view_team method to provide the needed information to view the grade heat map.  Then the update functionality is primarily implemented in the needed edit method which supplies information before the update and the update method has been vastly modified from its old implementation where it was not actually saving objects, we have replaced that with a proper update that modifies the grade and comment similarly to how the old save_grade_and_comment_for_submission method used to work.&lt;br /&gt;
===SOLID Principles===&lt;br /&gt;
Overall we strove to meet SOLID guidelines by limiting the scope of the controller back down to its intended core functionality.  This helped satisfy the single responsibility principle by removing additional functionality beyond the intended scope of this class.  We have also significantly cut down on the required helpers needed for these operations through our implementation of a new model participant_scores which helps serve the singular goal of keeping track of score information for questions on an assignment for a given participant. We have also improved the maintainability of the code by making our methods more atomic which should promote extension outside of our methods for new functionality satisfying the Open/Close principle. The remaining three principles did not really apply to this project as the grades_controller has minimal interactions with it's superclass and has no independent model that it controls or is responsible for governing.&lt;br /&gt;
===DRY principle===&lt;br /&gt;
To satisfy the don't repeat yourself principle we sought to make private helper methods to abstract repeated code that was adding complexity to our methods.  One such method is the get_data_for_heat_map method which replaces a substantial amount of what used to be complex and repeated code, which has now been significantly simplified for readability.  Please see the snippet below for the new method, it's primary goal is to set the instance variables of the controller as needed so we can prepare data for the heat map as needed in the front end.  We also relocated complex code that did not aid in the readability into helper methods which have also been refactored, the main goal of this was to promote readability in the main endpoint methods remove unnecessary clutter from the code, and limit code repetition in future modifications by providing modular helper methods for functionality that we believe may need to be repeated in future enhancements such as listing the questions or querying review grades.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Provides data for the heat maps in the view statements&lt;br /&gt;
  def get_data_for_heat_map(id)&lt;br /&gt;
    # Finds the assignment&lt;br /&gt;
    @assignment = Assignment.find(id)&lt;br /&gt;
    # Extracts the questionnaires&lt;br /&gt;
    @questions = filter_questionnaires(@assignment)&lt;br /&gt;
    @scores = review_grades(@assignment, @questions)&lt;br /&gt;
    @review_score_count = @scores[:teams].length # After rejecting nil scores need original length to iterate over hash&lt;br /&gt;
    @averages = vector(@scores)&lt;br /&gt;
    @avg_of_avg = mean(@averages)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Testing Details===&lt;br /&gt;
The test file can be located at:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spec/requests/api/v1/grades_controller_spec.rb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''action_allowed'''&lt;br /&gt;
** Passes in the view action and an assignment we wish to view. Determines if the user has the appropriate permissions to view it.&lt;br /&gt;
*'''view'''&lt;br /&gt;
** Passes in the id of the assignment and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''view_team'''&lt;br /&gt;
** Pasess in the assignment id and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''edit'''&lt;br /&gt;
** Passes in the id of the assignment and expects the participant's id, the same assignment's id, '''questions''', and '''scores'''.&lt;br /&gt;
*'''instructor_review'''&lt;br /&gt;
** Passes in the id of a participant and expects '''controller''', '''action''', the same participant id, and the instructor.&lt;br /&gt;
*'''update'''&lt;br /&gt;
** Passes in a participant id and a body which contains '''grade_for_submission''' (integer) and '''comment_for_submission''' (string). Expects the same grade, comment, '''action''', and participant's id.&lt;br /&gt;
&lt;br /&gt;
'''Rswag UI'''&lt;br /&gt;
[[File:Grades_controller_test_fall_2024.png|700px|An image showing the rswag ui of accepted test results.]]&lt;br /&gt;
=Final project additions=&lt;br /&gt;
==The Problem and Remaining Work==&lt;br /&gt;
While working on our OSS project we ran into substantial difficulties with testing our controller.  The primary reason for this is that the grades_controller is one of the first controller classes in the reimplementation backend that does not have a primary model associated with it.  This is because it does not seem prudent to make a grades model, as scores can be held and tracked as fields in other objects as primitives so this abstraction would not be particularly helpful.  However, this poses an interesting challenge when testing and reimplementing the controller.  Specifically, the dependency on the successful initialization of numerous models throughout the controller including Assignment, Participant, and Team to name a few of the model classes required for operations within the grades_controller for the present create and edit CRUD operations implemented within.  During our OSS project, we were able to slim down the controller and implement more elegant and atomic solutions to the tasks that the original controller was responsible for with some refactoring and reimplementation of various methods.  However, even with these changes, the grades_controller is still dependent on several other classes and their interactions within the system being initialized and in a valid state in order to perform (or test) the required operations.&lt;br /&gt;
&lt;br /&gt;
The primary difficulty in testing our controller as indicated above was this high dependency on other models for correct functionality.  Because of this, we had to construct and instantiate several different models in our test code.  This, in a vacuum, may not be an issue.  However, as the reimplementation backend codebase continues to grow this issue has the potential to become a recurring one where the ultimate result will be several violations of the DRY principle in the testing suite instantiating needed objects inside of controller tests similarly to the way that we had to do this at the start.  In the current codebase, the only models containing factory code are student_task, join_team_request, bookmark, and user, making this substantially shy of the thirty-six models currently residing within the reimplementation_backend repository.  We will seek to change this in order to limit the likelihood of DRY violations in the test suite moving forward to improve code maintainability and consistency.  This should also directly benefit future students who will not need to struggle with implementing testing for dependent controllers.  It should also make future refactors much less painful in terms of changing models breaking test cases, if the models are built in factories these issues may be rectified for all failing locations within the factory class rather than requiring the modification of several test files in the system.&lt;br /&gt;
&lt;br /&gt;
==Our solution==&lt;br /&gt;
Our solution to improving our OSS submission and the overall codebase is four-pronged.  This includes expanding the factory suite to include many additional models.  Our second plan is to improve our test cases and our overall test plan to be more comprehensive of all branches present in our code to conduct more thorough testing using our new factories.  Our third change will be to modify the seeding files for the db in order to facilitate manual testing with RSwag.  Finally our fourth goal for the project is to improve our RSwag UI by implementing the previous three steps and then ensuring that manual testing capability is achieved and correct.&lt;br /&gt;
===Expanded Factory Suite===&lt;br /&gt;
For our final project we are seeking to improve the code base by expanding the factory suite to include factories for most of the 37 models present in the reimplementation backend repository. The rationale behind this decision is to improve the testing capabilities of all controllers either currently in the system or ones that will be added. As the code base grows, we expect an increased interdependency of the controllers on the model classes. Without factory classes, this would result in an opportunity for several DRY violations in the test suite. This hinders the maintainability of the code base and as small changes in the models could break the entire test suite and would need to be solved individually in every test case; however, with factories, we would only need to fix the code within the factories to reflect the new code structure and the test cases will remain largely unchanged. We would also suggest that factories be continuously updated as new models are added so that it aids in future maintainability.&lt;br /&gt;
&lt;br /&gt;
===Improved Test Plan===&lt;br /&gt;
* action_allowed&lt;br /&gt;
** If the user is a TA or higher, then a successful status will be returned for all actions.&lt;br /&gt;
** If the user is a student and requests to view their team then, then a successful status will be returned.&lt;br /&gt;
** Otherwise, a status of prohibited is rendered regardless of the action.&lt;br /&gt;
* view&lt;br /&gt;
** A successful status, the scores, the assignment, the averages, the meta average, and the review score count are all rendered so that the heat map can be displayed. &lt;br /&gt;
* view_team&lt;br /&gt;
** A successful status, the scores, the assignment with filtered questionnaire authors , the averages, the meta average, and the review score count are all rendered so that the heat map can be displayed. &lt;br /&gt;
* edit&lt;br /&gt;
** If the assignment participant is not found, then a not found status is rendered.&lt;br /&gt;
** Otherwise, a successful status, the participant, the questions, the scores, and the assignment are all rendered.&lt;br /&gt;
* instructor_review&lt;br /&gt;
** If the assignment participant is not found, then a not found status is rendered.&lt;br /&gt;
** If the instructor review is new then a response is rendered to tell the front end to go to the response controllers new action with the reviews mapping's id.&lt;br /&gt;
** Otherwise, a response is rendered to tell the front end to go to the response controller's edit action with the review's id.&lt;br /&gt;
* update&lt;br /&gt;
** If the team cannot be saved, then a bad request status is rendered.&lt;br /&gt;
** Otherwise, a response is rendered to tell the front end to go to the grades controller's view team action with the participant's id.&lt;br /&gt;
====Flow Chart====&lt;br /&gt;
[[File:Decision_tree.png|700px|An image showing flow chart]]&lt;br /&gt;
&lt;br /&gt;
===Modified db seeding===&lt;br /&gt;
Currently the file '''seeds.rb''' contains only an institution and admin user. To streamline testing and set up appropriate models, we will make sure the file contains the following:&lt;br /&gt;
* An assignment instance&lt;br /&gt;
* A participant instance&lt;br /&gt;
* A team instance&lt;br /&gt;
* An instructor instance&lt;br /&gt;
To perform testing for the API endpoints, these are the minimum model instances required. The goal of this change is to make sure we can handle manually testing the grades controller with the rswag UI. This is specifically for the reimplementation of the backend. There is an absence of several necessary POST API endpoints implementing CREATE operations. Without these seeded into the database, we would need to cover more implementation on endpoints.&lt;br /&gt;
&lt;br /&gt;
===Functional RSwagUI visualizations and manual testing capability===&lt;br /&gt;
Currently, we have the endpoint visualizations set up on RSwag's UI, and just need to complete the previous steps for visualized results.  This will also ensure that our API endpoints are fully compatible with manual testing in the UI which is beneficial for various reasons.  Including testing new edge cases as they come up or the code expands before even making a unit test for simple things (although in the future for maintainability if a new edge case is discovered it should be added to the test suite).  This will allow future students to test our endpoints using the UI, and we imagine this will be particularly helpful for the future teams working on the frontend as they will be able to manually run their API requests and see the JSON response they are getting in one window to manually check their frontend calls.  This should help speed up their debugging process or clear up any uncertainty in behavior beyond the current code documentation if any remains.&lt;br /&gt;
&lt;br /&gt;
===Grades Controller Changes (Improvements based on OSS Project Feedback)===&lt;br /&gt;
* We reduced the complexity of the scores data structure. We started with a quadruple-layered hash map and reduced it to a simple hash map with two branches. This was facilitated &lt;br /&gt;
through the participants' scores model.&lt;br /&gt;
* The complexity fixes were primarily done through modifying '''review_grades'''.&lt;br /&gt;
** Instead of handling '''scores[:teams][team_id][:scores][:avg]''', we changed it to be '''scores[:teams][team_id]'''.&lt;br /&gt;
'''Before:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
team_id = team.id.to_s.to_sym&lt;br /&gt;
      scores[:teams][team_id] ||= { scores: { avg: 0 } }&lt;br /&gt;
&lt;br /&gt;
      # Calculate average score for the team&lt;br /&gt;
      team_scores = participant_scores.map { |s| s[:score].to_f / s[:total_score] * 100 }&lt;br /&gt;
      scores[:teams][team_id][:scores][:avg] = team_scores.sum / team_scores.size&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''After:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
scores[:teams][team_id] ||= 0&lt;br /&gt;
&lt;br /&gt;
      # Calculate average score for the team&lt;br /&gt;
      team_scores = participant_scores.map { |s| s[:score].to_f / s[:total_score] * 100 }&lt;br /&gt;
      scores[:teams][team_id] = team_scores.sum / team_scores.size&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* We changed the logic for '''vector'''&lt;br /&gt;
** We renamed it to: '''filter_scores'''&lt;br /&gt;
** Thanks to the simplification of the scores data structure, the function no longer violates the '''DRY Principle''' and is more readable.&lt;br /&gt;
'''Before:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    scores[:teams].reject! { |_k, v| v[:scores][:avg].nil? }&lt;br /&gt;
    scores[:teams].map { |_k, v| v[:scores][:avg].to_i }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''After:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    team_scores&lt;br /&gt;
      .compact&lt;br /&gt;
      .map { |team| team.is_a?(Array) ? team[1].to_i : team.to_i }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* We updated the documentation for '''edit''' and '''instructor_review''' in order to make it clear what the functions accomplished, why, and how.&lt;br /&gt;
* We changed the JSON rendering for '''view_team''' and '''view'''. They were previously returning duplicate data within our scores data structure. Since the modification, it is only returning labeled data that is easily accessible without manipulating the hash.&lt;br /&gt;
* We modified the internal data structure usage, only passing the participants or team branch of the scores data structure, instead of passing the previous structure around.&lt;br /&gt;
&lt;br /&gt;
===Future Implementation===&lt;br /&gt;
* The grades controller still has dependencies with other controllers modifying values used by this class, that will be reimplemented in the future. Specifically, the participant's scores model needs to be populated in the response controller when it is reimplemented in the future. &lt;br /&gt;
* Additionally, any future views requiring heatmap support will be able to utilize our private helper methods that were designed to be flexible in the grades controller with consistent data filtering. Additional filters will need to be added as separate code, rather than modifying ours to follow the open/closed principle.&lt;br /&gt;
* The professor instructed us to use the old authorization helper file, which is fine for this work in progress system. However, this file will need to be updated in the future internally to reflect the changes to web token-based authentication. Presently, the helper file assumes we use session-based authentication in the back end which is no longer the case. However, it's important to note this still works in the testing environment.&lt;br /&gt;
&lt;br /&gt;
=Team and Prior information=&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;br /&gt;
&lt;br /&gt;
==Previous Iterations==&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=159932</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=159932"/>
		<updated>2024-12-01T20:39:28Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: /* Grades Controller Changes (Improvements based on OSS Project Feedback) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
===[https://drive.google.com/file/d/1lgFLevdhs7PTFpibxflQfB45nOXW04jA/view?usp=sharing Swagger Video Submission]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents. Additionally, we will be testing the controller with rswag.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor grade_controller.rb, which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
API::V1::GradesController utilizes action-based permissions through action_allowed to provide broader functionality to instructors versus students. With the frontend systems of the Grades Controller relying on heat map systems, view and view_team provide the detailed grading information to populate them (from the student perspective, reviewer identities are kept hidden). The edit method retrieves the relevant assignment to be modified by the frontend view. For accessing reviews, instructor_review is utilized, leading to access of previous reviews or instantiating new ones. Finally, grade changes are saved through the update function, which additionally covers comment feedback.&lt;br /&gt;
&lt;br /&gt;
This controller structure aligns closely with the traditional CRUD operations providing an organized way to handle grade management. The view and view_team actions are for the Read functionality, allowing both instructors and students to access and review grade data based on their roles. The Create aspect is handled in instructor_review, which either retrieves existing reviews or initiates new ones as needed, ensuring that instructors can easily add comments or feedback for an assignment.&lt;br /&gt;
&lt;br /&gt;
The Update action is fulfilled by update, which is responsible for saving new grading data and feedback from instructors. The Delete functionality is not something the grades_controller is responsible for handling.&lt;br /&gt;
&lt;br /&gt;
This CRUD focused approach makes sure that the refactored grade_controller.rb is efficient and easily maintainable, while offering both instructors and students a seamless experience in managing and reviewing assignment grades. The refactor further enhances clarity and accessibility, aiming to make each action intuitive and easily accessible to the relevant users within Expertiza.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's point of view, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's point of view which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's point of view&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
===Rationale for Changes===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
|-&lt;br /&gt;
|Added a new suite of API endpoint tests that are compatible with Rswag and tested our API endpoints thoroughly, additionally added factories for several projects in the system.&lt;br /&gt;
|As with any software change in a large system, testing is extremely important, so we wrote comprehensive tests for our endpoints.  Additionally, since the grades_controller is dependent on many other models (mainly because there is no grades model).  These changes will help future projects by providing factory methods for various models that did not currently have them in the system which should make testing for other groups easier in the future.&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Code Snippet===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Determines if the current user is able to perform :action as specified by the path parameter&lt;br /&gt;
  # If the user has the role of TA or higher they are granted access to all operations beyond view_team&lt;br /&gt;
  # Uses a switch statement for easy maintainability if added functionality is ever needed for students or&lt;br /&gt;
  # additional roles, to add more functionality simply add additional switch cases in the same syntax with&lt;br /&gt;
  # case 'action' and then some boolean check determining if that is allowed or forbidden.&lt;br /&gt;
  # GET /api/v1/grades/:action/action_allowed&lt;br /&gt;
  def action_allowed&lt;br /&gt;
    permitted = case params[:action]&lt;br /&gt;
                when 'view_team'&lt;br /&gt;
                  view_team_allowed?&lt;br /&gt;
                else&lt;br /&gt;
                  user_ta_privileges?&lt;br /&gt;
                end&lt;br /&gt;
    render json: { allowed: permitted }, status: permitted ? :ok : :forbidden&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides the needed functionality of querying needed values from the backend db and returning them to build the&lt;br /&gt;
  # heat map in the frontend from the TA/staff view.  These values are set in the get_data_for_heat_map method&lt;br /&gt;
  # which takes the assignment id as a parameter.&lt;br /&gt;
  # GET /api/v1/grades/:id/view&lt;br /&gt;
  def view&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    render json: { scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                   review_score_count: @review_score_count }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides all relevant data for the student perspective for the heat map page as well as the&lt;br /&gt;
  # needed information to showcase the questionnaires from the student view.  Additionally, handles the removal of user&lt;br /&gt;
  # identification in the reviews within the hide_reviewers_rom_student method.&lt;br /&gt;
  # GET /api/v1/grades/:id/view_team&lt;br /&gt;
  def view_team&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    @scores[:participants] = hide_reviewers_from_student&lt;br /&gt;
    questionnaires = @assignment.questionnaires&lt;br /&gt;
    questions = retrieve_questions(questionnaires, @assignment.id)&lt;br /&gt;
    render json: {scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                  review_score_count: @review_score_count, questions: questions }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Sets information required for editing the grade information, this includes the participant, questions, scores, and&lt;br /&gt;
  # assignment&lt;br /&gt;
  # GET /api/v1/grades/:id/edit&lt;br /&gt;
  def edit&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: {message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot;}, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    questions = list_questions(assignment)&lt;br /&gt;
    scores = review_grades(assignment, questions)&lt;br /&gt;
    render json: {participant: participant, questions: questions, scores: scores, assignment: assignment}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides functionality that handles informing the frontend which controller and action to direct to for instructor&lt;br /&gt;
  # review given the current state of the system.  The intended controller to handle the creation or editing of a review&lt;br /&gt;
  # is the response controller, however this method just determines if a new review must be made based on figuring out&lt;br /&gt;
  # whether or not an associated review_mapping exists from the participant already.  If one does they should go to&lt;br /&gt;
  # Response#edit and if one does not they should go to Response#new.  Only ever returns a status of ok.&lt;br /&gt;
  # GET /api/v1/grades/:id/instructor_review&lt;br /&gt;
  def instructor_review&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: { message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot; }, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    review_mapping = find_participant_review_mapping(participant)&lt;br /&gt;
    if review_mapping.new_record?&lt;br /&gt;
      render json: { controller: 'response', action: 'new', id: review_mapping.map_id,&lt;br /&gt;
                     return: 'instructor'}, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      review = Response.find_by(map_id: review_mapping.map_id)&lt;br /&gt;
      render json: { controller: 'response', action: 'edit', id: review.id, return: 'instructor'}, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Update method for the grade associated with a team, allows an instructor to upgrade a team's grade with a grade&lt;br /&gt;
  # and a comment on their assignment for submission.  The team is then saved with this change in order to be accessed&lt;br /&gt;
  # elsewhere in the code for needed scoring evaluations.  If a failure occurs while saving the team then this will&lt;br /&gt;
  # return a bad_request response complete with a message and the global ERROR_INFO which can be set elsewhere for&lt;br /&gt;
  # further error handling mechanisms&lt;br /&gt;
  # PATCH /api/v1/grades/:participant_id/update/:grade_for_submission&lt;br /&gt;
  def update&lt;br /&gt;
    participant = AssignmentParticipant.find_by(id: params[:participant_id])&lt;br /&gt;
&lt;br /&gt;
    team = participant.team&lt;br /&gt;
    team.grade_for_submission = params[:grade_for_submission]&lt;br /&gt;
    team.comment_for_submission = params[:comment_for_submission]&lt;br /&gt;
    begin&lt;br /&gt;
      team.save&lt;br /&gt;
    rescue StandardError =&amp;gt; e&lt;br /&gt;
      render json: {message: &amp;quot;Error occurred while updating grade for team #{team.id}&amp;quot;,&lt;br /&gt;
                    error: e.message }, status: :bad_request&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: { controller: 'grades', action: 'view_team', id: participant.id}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===CRUD functionality===&lt;br /&gt;
Before we did our refactor and reimplementation the grades_controller contained several unnecessary methods as well as functions vastly beyond the CRUD operations that belong within a controller like this.  The two CRUD operations that are presently in the system for the grades_controller are read and updated.  The read operation is implemented within the view and view_team method to provide the needed information to view the grade heat map.  Then the update functionality is primarily implemented in the needed edit method which supplies information before the update and the update method has been vastly modified from its old implementation where it was not actually saving objects, we have replaced that with a proper update that modifies the grade and comment similarly to how the old save_grade_and_comment_for_submission method used to work.&lt;br /&gt;
===SOLID Principles===&lt;br /&gt;
Overall we strove to meet SOLID guidelines by limiting the scope of the controller back down to its intended core functionality.  This helped satisfy the single responsibility principle by removing additional functionality beyond the intended scope of this class.  We have also significantly cut down on the required helpers needed for these operations through our implementation of a new model participant_scores which helps serve the singular goal of keeping track of score information for questions on an assignment for a given participant. We have also improved the maintainability of the code by making our methods more atomic which should promote extension outside of our methods for new functionality satisfying the Open/Close principle. The remaining three principles did not really apply to this project as the grades_controller has minimal interactions with it's superclass and has no independent model that it controls or is responsible for governing.&lt;br /&gt;
===DRY principle===&lt;br /&gt;
To satisfy the don't repeat yourself principle we sought to make private helper methods to abstract repeated code that was adding complexity to our methods.  One such method is the get_data_for_heat_map method which replaces a substantial amount of what used to be complex and repeated code, which has now been significantly simplified for readability.  Please see the snippet below for the new method, it's primary goal is to set the instance variables of the controller as needed so we can prepare data for the heat map as needed in the front end.  We also relocated complex code that did not aid in the readability into helper methods which have also been refactored, the main goal of this was to promote readability in the main endpoint methods remove unnecessary clutter from the code, and limit code repetition in future modifications by providing modular helper methods for functionality that we believe may need to be repeated in future enhancements such as listing the questions or querying review grades.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Provides data for the heat maps in the view statements&lt;br /&gt;
  def get_data_for_heat_map(id)&lt;br /&gt;
    # Finds the assignment&lt;br /&gt;
    @assignment = Assignment.find(id)&lt;br /&gt;
    # Extracts the questionnaires&lt;br /&gt;
    @questions = filter_questionnaires(@assignment)&lt;br /&gt;
    @scores = review_grades(@assignment, @questions)&lt;br /&gt;
    @review_score_count = @scores[:teams].length # After rejecting nil scores need original length to iterate over hash&lt;br /&gt;
    @averages = vector(@scores)&lt;br /&gt;
    @avg_of_avg = mean(@averages)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Testing Details===&lt;br /&gt;
The test file can be located at:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spec/requests/api/v1/grades_controller_spec.rb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''action_allowed'''&lt;br /&gt;
** Passes in the view action and an assignment we wish to view. Determines if the user has the appropriate permissions to view it.&lt;br /&gt;
*'''view'''&lt;br /&gt;
** Passes in the id of the assignment and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''view_team'''&lt;br /&gt;
** Pasess in the assignment id and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''edit'''&lt;br /&gt;
** Passes in the id of the assignment and expects the participant's id, the same assignment's id, '''questions''', and '''scores'''.&lt;br /&gt;
*'''instructor_review'''&lt;br /&gt;
** Passes in the id of a participant and expects '''controller''', '''action''', the same participant id, and the instructor.&lt;br /&gt;
*'''update'''&lt;br /&gt;
** Passes in a participant id and a body which contains '''grade_for_submission''' (integer) and '''comment_for_submission''' (string). Expects the same grade, comment, '''action''', and participant's id.&lt;br /&gt;
&lt;br /&gt;
'''Rswag UI'''&lt;br /&gt;
[[File:Grades_controller_test_fall_2024.png|700px|An image showing the rswag ui of accepted test results.]]&lt;br /&gt;
=Final project additions=&lt;br /&gt;
==The Problem and Remaining Work==&lt;br /&gt;
While working on our OSS project we ran into substantial difficulties with testing our controller.  The primary reason for this is that the grades_controller is one of the first controller classes in the reimplementation backend that does not have a primary model associated with it.  This is because it does not seem prudent to make a grades model, as scores can be held and tracked as fields in other objects as primitives so this abstraction would not be particularly helpful.  However, this poses an interesting challenge when testing and reimplementing the controller.  Specifically, the dependency on the successful initialization of numerous models throughout the controller including Assignment, Participant, and Team to name a few of the model classes required for operations within the grades_controller for the present create and edit CRUD operations implemented within.  During our OSS project, we were able to slim down the controller and implement more elegant and atomic solutions to the tasks that the original controller was responsible for with some refactoring and reimplementation of various methods.  However, even with these changes, the grades_controller is still dependent on several other classes and their interactions within the system being initialized and in a valid state in order to perform (or test) the required operations.&lt;br /&gt;
&lt;br /&gt;
The primary difficulty in testing our controller as indicated above was this high dependency on other models for correct functionality.  Because of this, we had to construct and instantiate several different models in our test code.  This, in a vacuum, may not be an issue.  However, as the reimplementation backend codebase continues to grow this issue has the potential to become a recurring one where the ultimate result will be several violations of the DRY principle in the testing suite instantiating needed objects inside of controller tests similarly to the way that we had to do this at the start.  In the current codebase, the only models containing factory code are student_task, join_team_request, bookmark, and user, making this substantially shy of the thirty-six models currently residing within the reimplementation_backend repository.  We will seek to change this in order to limit the likelihood of DRY violations in the test suite moving forward to improve code maintainability and consistency.  This should also directly benefit future students who will not need to struggle with implementing testing for dependent controllers.  It should also make future refactors much less painful in terms of changing models breaking test cases, if the models are built in factories these issues may be rectified for all failing locations within the factory class rather than requiring the modification of several test files in the system.&lt;br /&gt;
&lt;br /&gt;
==Our solution==&lt;br /&gt;
Our solution to improving our OSS submission and the overall codebase is four-pronged.  This includes expanding the factory suite to include many additional models.  Our second plan is to improve our test cases and our overall test plan to be more comprehensive of all branches present in our code to conduct more thorough testing using our new factories.  Our third change will be to modify the seeding files for the db in order to facilitate manual testing with RSwag.  Finally our fourth goal for the project is to improve our RSwag UI by implementing the previous three steps and then ensuring that manual testing capability is achieved and correct.&lt;br /&gt;
===Expanded Factory Suite===&lt;br /&gt;
For our final project we are seeking to improve the code base by expanding the factory suite to include factories for most of the 37 models present in the reimplementation backend repository. The rationale behind this decision is to improve the testing capabilities of all controllers either currently in the system or ones that will be added. As the code base grows, we expect an increased interdependency of the controllers on the model classes. Without factory classes, this would result in an opportunity for several DRY violations in the test suite. This hinders the maintainability of the code base and as small changes in the models could break the entire test suite and would need to be solved individually in every test case; however, with factories, we would only need to fix the code within the factories to reflect the new code structure and the test cases will remain largely unchanged. We would also suggest that factories be continuously updated as new models are added so that it aids in future maintainability.&lt;br /&gt;
&lt;br /&gt;
===Improved Test Plan===&lt;br /&gt;
* action_allowed&lt;br /&gt;
** If the user is a TA or higher, then a successful status will be returned for all actions.&lt;br /&gt;
** If the user is a student and requests to view their team then, then a successful status will be returned.&lt;br /&gt;
** Otherwise, a status of prohibited is rendered regardless of the action.&lt;br /&gt;
* view&lt;br /&gt;
** A successful status, the scores, the assignment, the averages, the meta average, and the review score count are all rendered so that the heat map can be displayed. &lt;br /&gt;
* view_team&lt;br /&gt;
** A successful status, the scores, the assignment with filtered questionnaire authors , the averages, the meta average, and the review score count are all rendered so that the heat map can be displayed. &lt;br /&gt;
* edit&lt;br /&gt;
** If the assignment participant is not found, then a not found status is rendered.&lt;br /&gt;
** Otherwise, a successful status, the participant, the questions, the scores, and the assignment are all rendered.&lt;br /&gt;
* instructor_review&lt;br /&gt;
** If the assignment participant is not found, then a not found status is rendered.&lt;br /&gt;
** If the instructor review is new then a response is rendered to tell the front end to go to the response controllers new action with the reviews mapping's id.&lt;br /&gt;
** Otherwise, a response is rendered to tell the front end to go to the response controller's edit action with the review's id.&lt;br /&gt;
* update&lt;br /&gt;
** If the team cannot be saved, then a bad request status is rendered.&lt;br /&gt;
** Otherwise, a response is rendered to tell the front end to go to the grades controller's view team action with the participant's id.&lt;br /&gt;
====Flow Chart====&lt;br /&gt;
[[File:Decision_tree.png|700px|An image showing flow chart]]&lt;br /&gt;
&lt;br /&gt;
===Modified db seeding===&lt;br /&gt;
Currently the file '''seeds.rb''' contains only an institution and admin user. To streamline testing and set up appropriate models, we will make sure the file contains the following:&lt;br /&gt;
* An assignment instance&lt;br /&gt;
* A participant instance&lt;br /&gt;
* A team instance&lt;br /&gt;
* An instructor instance&lt;br /&gt;
To perform testing for the API endpoints, these are the minimum model instances required. The goal of this change is to make sure we can handle manually testing the grades controller with the rswag UI. This is specifically for the reimplementation of the backend. There is an absence of several necessary POST API endpoints implementing CREATE operations. Without these seeded into the database, we would need to cover more implementation on endpoints.&lt;br /&gt;
&lt;br /&gt;
===Functional RSwagUI visualizations and manual testing capability===&lt;br /&gt;
Currently, we have the endpoint visualizations set up on RSwag's UI, and just need to complete the previous steps for visualized results.  This will also ensure that our API endpoints are fully compatible with manual testing in the UI which is beneficial for various reasons.  Including testing new edge cases as they come up or the code expands before even making a unit test for simple things (although in the future for maintainability if a new edge case is discovered it should be added to the test suite).  This will allow future students to test our endpoints using the UI, and we imagine this will be particularly helpful for the future teams working on the frontend as they will be able to manually run their API requests and see the JSON response they are getting in one window to manually check their frontend calls.  This should help speed up their debugging process or clear up any uncertainty in behavior beyond the current code documentation if any remains.&lt;br /&gt;
&lt;br /&gt;
===Grades Controller Changes (Improvements based on OSS Project Feedback)===&lt;br /&gt;
* We reduced the complexity of the scores data structure. We started with a quadruple-layered hash map and reduced it to a simple hash map with two branches. This was facilitated &lt;br /&gt;
through the participants' scores model.&lt;br /&gt;
* The complexity fixes were primarily done through modifying '''review_grades'''.&lt;br /&gt;
** Instead of handling '''scores[:teams][team_id][:scores][:avg]''', we changed it to be '''scores[:teams][team_id]'''.&lt;br /&gt;
'''Before:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
team_id = team.id.to_s.to_sym&lt;br /&gt;
      scores[:teams][team_id] ||= { scores: { avg: 0 } }&lt;br /&gt;
&lt;br /&gt;
      # Calculate average score for the team&lt;br /&gt;
      team_scores = participant_scores.map { |s| s[:score].to_f / s[:total_score] * 100 }&lt;br /&gt;
      scores[:teams][team_id][:scores][:avg] = team_scores.sum / team_scores.size&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''After:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
scores[:teams][team_id] ||= 0&lt;br /&gt;
&lt;br /&gt;
      # Calculate average score for the team&lt;br /&gt;
      team_scores = participant_scores.map { |s| s[:score].to_f / s[:total_score] * 100 }&lt;br /&gt;
      scores[:teams][team_id] = team_scores.sum / team_scores.size&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* We changed the logic for '''vector'''&lt;br /&gt;
** We renamed it to: '''filter_scores'''&lt;br /&gt;
** Thanks to the simplification of the scores data structure, the function no longer violates the '''DRY Principle''' and is more readable.&lt;br /&gt;
'''Before:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    scores[:teams].reject! { |_k, v| v[:scores][:avg].nil? }&lt;br /&gt;
    scores[:teams].map { |_k, v| v[:scores][:avg].to_i }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''After:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    team_scores&lt;br /&gt;
      .compact&lt;br /&gt;
      .map { |team| team.is_a?(Array) ? team[1].to_i : team.to_i }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* We updated the documentation for '''edit''' and '''instructor_review''' in order to make it clear what the functions accomplished, why, and how.&lt;br /&gt;
* We changed the JSON rendering for '''view_team''' and '''view'''. They were previously returning duplicate data within our scores data structure. Since the modification, it is only returning labeled data that is easily accessible without manipulating the hash.&lt;br /&gt;
* We modified the internal data structure usage, only passing the participants or team branch of the scores data structure, instead of passing the previous structure around.&lt;br /&gt;
&lt;br /&gt;
===Future Implementation===&lt;br /&gt;
&lt;br /&gt;
=Team and Prior information=&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;br /&gt;
&lt;br /&gt;
==Previous Iterations==&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=159931</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=159931"/>
		<updated>2024-12-01T20:38:30Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: /* Grades Controller Changes (Improvements based on OSS Project Feedback) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
===[https://drive.google.com/file/d/1lgFLevdhs7PTFpibxflQfB45nOXW04jA/view?usp=sharing Swagger Video Submission]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents. Additionally, we will be testing the controller with rswag.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor grade_controller.rb, which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
API::V1::GradesController utilizes action-based permissions through action_allowed to provide broader functionality to instructors versus students. With the frontend systems of the Grades Controller relying on heat map systems, view and view_team provide the detailed grading information to populate them (from the student perspective, reviewer identities are kept hidden). The edit method retrieves the relevant assignment to be modified by the frontend view. For accessing reviews, instructor_review is utilized, leading to access of previous reviews or instantiating new ones. Finally, grade changes are saved through the update function, which additionally covers comment feedback.&lt;br /&gt;
&lt;br /&gt;
This controller structure aligns closely with the traditional CRUD operations providing an organized way to handle grade management. The view and view_team actions are for the Read functionality, allowing both instructors and students to access and review grade data based on their roles. The Create aspect is handled in instructor_review, which either retrieves existing reviews or initiates new ones as needed, ensuring that instructors can easily add comments or feedback for an assignment.&lt;br /&gt;
&lt;br /&gt;
The Update action is fulfilled by update, which is responsible for saving new grading data and feedback from instructors. The Delete functionality is not something the grades_controller is responsible for handling.&lt;br /&gt;
&lt;br /&gt;
This CRUD focused approach makes sure that the refactored grade_controller.rb is efficient and easily maintainable, while offering both instructors and students a seamless experience in managing and reviewing assignment grades. The refactor further enhances clarity and accessibility, aiming to make each action intuitive and easily accessible to the relevant users within Expertiza.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's point of view, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's point of view which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's point of view&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
===Rationale for Changes===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
|-&lt;br /&gt;
|Added a new suite of API endpoint tests that are compatible with Rswag and tested our API endpoints thoroughly, additionally added factories for several projects in the system.&lt;br /&gt;
|As with any software change in a large system, testing is extremely important, so we wrote comprehensive tests for our endpoints.  Additionally, since the grades_controller is dependent on many other models (mainly because there is no grades model).  These changes will help future projects by providing factory methods for various models that did not currently have them in the system which should make testing for other groups easier in the future.&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Code Snippet===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Determines if the current user is able to perform :action as specified by the path parameter&lt;br /&gt;
  # If the user has the role of TA or higher they are granted access to all operations beyond view_team&lt;br /&gt;
  # Uses a switch statement for easy maintainability if added functionality is ever needed for students or&lt;br /&gt;
  # additional roles, to add more functionality simply add additional switch cases in the same syntax with&lt;br /&gt;
  # case 'action' and then some boolean check determining if that is allowed or forbidden.&lt;br /&gt;
  # GET /api/v1/grades/:action/action_allowed&lt;br /&gt;
  def action_allowed&lt;br /&gt;
    permitted = case params[:action]&lt;br /&gt;
                when 'view_team'&lt;br /&gt;
                  view_team_allowed?&lt;br /&gt;
                else&lt;br /&gt;
                  user_ta_privileges?&lt;br /&gt;
                end&lt;br /&gt;
    render json: { allowed: permitted }, status: permitted ? :ok : :forbidden&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides the needed functionality of querying needed values from the backend db and returning them to build the&lt;br /&gt;
  # heat map in the frontend from the TA/staff view.  These values are set in the get_data_for_heat_map method&lt;br /&gt;
  # which takes the assignment id as a parameter.&lt;br /&gt;
  # GET /api/v1/grades/:id/view&lt;br /&gt;
  def view&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    render json: { scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                   review_score_count: @review_score_count }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides all relevant data for the student perspective for the heat map page as well as the&lt;br /&gt;
  # needed information to showcase the questionnaires from the student view.  Additionally, handles the removal of user&lt;br /&gt;
  # identification in the reviews within the hide_reviewers_rom_student method.&lt;br /&gt;
  # GET /api/v1/grades/:id/view_team&lt;br /&gt;
  def view_team&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    @scores[:participants] = hide_reviewers_from_student&lt;br /&gt;
    questionnaires = @assignment.questionnaires&lt;br /&gt;
    questions = retrieve_questions(questionnaires, @assignment.id)&lt;br /&gt;
    render json: {scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                  review_score_count: @review_score_count, questions: questions }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Sets information required for editing the grade information, this includes the participant, questions, scores, and&lt;br /&gt;
  # assignment&lt;br /&gt;
  # GET /api/v1/grades/:id/edit&lt;br /&gt;
  def edit&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: {message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot;}, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    questions = list_questions(assignment)&lt;br /&gt;
    scores = review_grades(assignment, questions)&lt;br /&gt;
    render json: {participant: participant, questions: questions, scores: scores, assignment: assignment}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides functionality that handles informing the frontend which controller and action to direct to for instructor&lt;br /&gt;
  # review given the current state of the system.  The intended controller to handle the creation or editing of a review&lt;br /&gt;
  # is the response controller, however this method just determines if a new review must be made based on figuring out&lt;br /&gt;
  # whether or not an associated review_mapping exists from the participant already.  If one does they should go to&lt;br /&gt;
  # Response#edit and if one does not they should go to Response#new.  Only ever returns a status of ok.&lt;br /&gt;
  # GET /api/v1/grades/:id/instructor_review&lt;br /&gt;
  def instructor_review&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: { message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot; }, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    review_mapping = find_participant_review_mapping(participant)&lt;br /&gt;
    if review_mapping.new_record?&lt;br /&gt;
      render json: { controller: 'response', action: 'new', id: review_mapping.map_id,&lt;br /&gt;
                     return: 'instructor'}, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      review = Response.find_by(map_id: review_mapping.map_id)&lt;br /&gt;
      render json: { controller: 'response', action: 'edit', id: review.id, return: 'instructor'}, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Update method for the grade associated with a team, allows an instructor to upgrade a team's grade with a grade&lt;br /&gt;
  # and a comment on their assignment for submission.  The team is then saved with this change in order to be accessed&lt;br /&gt;
  # elsewhere in the code for needed scoring evaluations.  If a failure occurs while saving the team then this will&lt;br /&gt;
  # return a bad_request response complete with a message and the global ERROR_INFO which can be set elsewhere for&lt;br /&gt;
  # further error handling mechanisms&lt;br /&gt;
  # PATCH /api/v1/grades/:participant_id/update/:grade_for_submission&lt;br /&gt;
  def update&lt;br /&gt;
    participant = AssignmentParticipant.find_by(id: params[:participant_id])&lt;br /&gt;
&lt;br /&gt;
    team = participant.team&lt;br /&gt;
    team.grade_for_submission = params[:grade_for_submission]&lt;br /&gt;
    team.comment_for_submission = params[:comment_for_submission]&lt;br /&gt;
    begin&lt;br /&gt;
      team.save&lt;br /&gt;
    rescue StandardError =&amp;gt; e&lt;br /&gt;
      render json: {message: &amp;quot;Error occurred while updating grade for team #{team.id}&amp;quot;,&lt;br /&gt;
                    error: e.message }, status: :bad_request&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: { controller: 'grades', action: 'view_team', id: participant.id}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===CRUD functionality===&lt;br /&gt;
Before we did our refactor and reimplementation the grades_controller contained several unnecessary methods as well as functions vastly beyond the CRUD operations that belong within a controller like this.  The two CRUD operations that are presently in the system for the grades_controller are read and updated.  The read operation is implemented within the view and view_team method to provide the needed information to view the grade heat map.  Then the update functionality is primarily implemented in the needed edit method which supplies information before the update and the update method has been vastly modified from its old implementation where it was not actually saving objects, we have replaced that with a proper update that modifies the grade and comment similarly to how the old save_grade_and_comment_for_submission method used to work.&lt;br /&gt;
===SOLID Principles===&lt;br /&gt;
Overall we strove to meet SOLID guidelines by limiting the scope of the controller back down to its intended core functionality.  This helped satisfy the single responsibility principle by removing additional functionality beyond the intended scope of this class.  We have also significantly cut down on the required helpers needed for these operations through our implementation of a new model participant_scores which helps serve the singular goal of keeping track of score information for questions on an assignment for a given participant. We have also improved the maintainability of the code by making our methods more atomic which should promote extension outside of our methods for new functionality satisfying the Open/Close principle. The remaining three principles did not really apply to this project as the grades_controller has minimal interactions with it's superclass and has no independent model that it controls or is responsible for governing.&lt;br /&gt;
===DRY principle===&lt;br /&gt;
To satisfy the don't repeat yourself principle we sought to make private helper methods to abstract repeated code that was adding complexity to our methods.  One such method is the get_data_for_heat_map method which replaces a substantial amount of what used to be complex and repeated code, which has now been significantly simplified for readability.  Please see the snippet below for the new method, it's primary goal is to set the instance variables of the controller as needed so we can prepare data for the heat map as needed in the front end.  We also relocated complex code that did not aid in the readability into helper methods which have also been refactored, the main goal of this was to promote readability in the main endpoint methods remove unnecessary clutter from the code, and limit code repetition in future modifications by providing modular helper methods for functionality that we believe may need to be repeated in future enhancements such as listing the questions or querying review grades.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Provides data for the heat maps in the view statements&lt;br /&gt;
  def get_data_for_heat_map(id)&lt;br /&gt;
    # Finds the assignment&lt;br /&gt;
    @assignment = Assignment.find(id)&lt;br /&gt;
    # Extracts the questionnaires&lt;br /&gt;
    @questions = filter_questionnaires(@assignment)&lt;br /&gt;
    @scores = review_grades(@assignment, @questions)&lt;br /&gt;
    @review_score_count = @scores[:teams].length # After rejecting nil scores need original length to iterate over hash&lt;br /&gt;
    @averages = vector(@scores)&lt;br /&gt;
    @avg_of_avg = mean(@averages)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Testing Details===&lt;br /&gt;
The test file can be located at:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spec/requests/api/v1/grades_controller_spec.rb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''action_allowed'''&lt;br /&gt;
** Passes in the view action and an assignment we wish to view. Determines if the user has the appropriate permissions to view it.&lt;br /&gt;
*'''view'''&lt;br /&gt;
** Passes in the id of the assignment and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''view_team'''&lt;br /&gt;
** Pasess in the assignment id and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''edit'''&lt;br /&gt;
** Passes in the id of the assignment and expects the participant's id, the same assignment's id, '''questions''', and '''scores'''.&lt;br /&gt;
*'''instructor_review'''&lt;br /&gt;
** Passes in the id of a participant and expects '''controller''', '''action''', the same participant id, and the instructor.&lt;br /&gt;
*'''update'''&lt;br /&gt;
** Passes in a participant id and a body which contains '''grade_for_submission''' (integer) and '''comment_for_submission''' (string). Expects the same grade, comment, '''action''', and participant's id.&lt;br /&gt;
&lt;br /&gt;
'''Rswag UI'''&lt;br /&gt;
[[File:Grades_controller_test_fall_2024.png|700px|An image showing the rswag ui of accepted test results.]]&lt;br /&gt;
=Final project additions=&lt;br /&gt;
==The Problem and Remaining Work==&lt;br /&gt;
While working on our OSS project we ran into substantial difficulties with testing our controller.  The primary reason for this is that the grades_controller is one of the first controller classes in the reimplementation backend that does not have a primary model associated with it.  This is because it does not seem prudent to make a grades model, as scores can be held and tracked as fields in other objects as primitives so this abstraction would not be particularly helpful.  However, this poses an interesting challenge when testing and reimplementing the controller.  Specifically, the dependency on the successful initialization of numerous models throughout the controller including Assignment, Participant, and Team to name a few of the model classes required for operations within the grades_controller for the present create and edit CRUD operations implemented within.  During our OSS project, we were able to slim down the controller and implement more elegant and atomic solutions to the tasks that the original controller was responsible for with some refactoring and reimplementation of various methods.  However, even with these changes, the grades_controller is still dependent on several other classes and their interactions within the system being initialized and in a valid state in order to perform (or test) the required operations.&lt;br /&gt;
&lt;br /&gt;
The primary difficulty in testing our controller as indicated above was this high dependency on other models for correct functionality.  Because of this, we had to construct and instantiate several different models in our test code.  This, in a vacuum, may not be an issue.  However, as the reimplementation backend codebase continues to grow this issue has the potential to become a recurring one where the ultimate result will be several violations of the DRY principle in the testing suite instantiating needed objects inside of controller tests similarly to the way that we had to do this at the start.  In the current codebase, the only models containing factory code are student_task, join_team_request, bookmark, and user, making this substantially shy of the thirty-six models currently residing within the reimplementation_backend repository.  We will seek to change this in order to limit the likelihood of DRY violations in the test suite moving forward to improve code maintainability and consistency.  This should also directly benefit future students who will not need to struggle with implementing testing for dependent controllers.  It should also make future refactors much less painful in terms of changing models breaking test cases, if the models are built in factories these issues may be rectified for all failing locations within the factory class rather than requiring the modification of several test files in the system.&lt;br /&gt;
&lt;br /&gt;
==Our solution==&lt;br /&gt;
Our solution to improving our OSS submission and the overall codebase is four-pronged.  This includes expanding the factory suite to include many additional models.  Our second plan is to improve our test cases and our overall test plan to be more comprehensive of all branches present in our code to conduct more thorough testing using our new factories.  Our third change will be to modify the seeding files for the db in order to facilitate manual testing with RSwag.  Finally our fourth goal for the project is to improve our RSwag UI by implementing the previous three steps and then ensuring that manual testing capability is achieved and correct.&lt;br /&gt;
===Expanded Factory Suite===&lt;br /&gt;
For our final project we are seeking to improve the code base by expanding the factory suite to include factories for most of the 37 models present in the reimplementation backend repository. The rationale behind this decision is to improve the testing capabilities of all controllers either currently in the system or ones that will be added. As the code base grows, we expect an increased interdependency of the controllers on the model classes. Without factory classes, this would result in an opportunity for several DRY violations in the test suite. This hinders the maintainability of the code base and as small changes in the models could break the entire test suite and would need to be solved individually in every test case; however, with factories, we would only need to fix the code within the factories to reflect the new code structure and the test cases will remain largely unchanged. We would also suggest that factories be continuously updated as new models are added so that it aids in future maintainability.&lt;br /&gt;
&lt;br /&gt;
===Improved Test Plan===&lt;br /&gt;
* action_allowed&lt;br /&gt;
** If the user is a TA or higher, then a successful status will be returned for all actions.&lt;br /&gt;
** If the user is a student and requests to view their team then, then a successful status will be returned.&lt;br /&gt;
** Otherwise, a status of prohibited is rendered regardless of the action.&lt;br /&gt;
* view&lt;br /&gt;
** A successful status, the scores, the assignment, the averages, the meta average, and the review score count are all rendered so that the heat map can be displayed. &lt;br /&gt;
* view_team&lt;br /&gt;
** A successful status, the scores, the assignment with filtered questionnaire authors , the averages, the meta average, and the review score count are all rendered so that the heat map can be displayed. &lt;br /&gt;
* edit&lt;br /&gt;
** If the assignment participant is not found, then a not found status is rendered.&lt;br /&gt;
** Otherwise, a successful status, the participant, the questions, the scores, and the assignment are all rendered.&lt;br /&gt;
* instructor_review&lt;br /&gt;
** If the assignment participant is not found, then a not found status is rendered.&lt;br /&gt;
** If the instructor review is new then a response is rendered to tell the front end to go to the response controllers new action with the reviews mapping's id.&lt;br /&gt;
** Otherwise, a response is rendered to tell the front end to go to the response controller's edit action with the review's id.&lt;br /&gt;
* update&lt;br /&gt;
** If the team cannot be saved, then a bad request status is rendered.&lt;br /&gt;
** Otherwise, a response is rendered to tell the front end to go to the grades controller's view team action with the participant's id.&lt;br /&gt;
====Flow Chart====&lt;br /&gt;
[[File:Decision_tree.png|700px|An image showing flow chart]]&lt;br /&gt;
&lt;br /&gt;
===Modified db seeding===&lt;br /&gt;
Currently the file '''seeds.rb''' contains only an institution and admin user. To streamline testing and set up appropriate models, we will make sure the file contains the following:&lt;br /&gt;
* An assignment instance&lt;br /&gt;
* A participant instance&lt;br /&gt;
* A team instance&lt;br /&gt;
* An instructor instance&lt;br /&gt;
To perform testing for the API endpoints, these are the minimum model instances required. The goal of this change is to make sure we can handle manually testing the grades controller with the rswag UI. This is specifically for the reimplementation of the backend. There is an absence of several necessary POST API endpoints implementing CREATE operations. Without these seeded into the database, we would need to cover more implementation on endpoints.&lt;br /&gt;
&lt;br /&gt;
===Functional RSwagUI visualizations and manual testing capability===&lt;br /&gt;
Currently, we have the endpoint visualizations set up on RSwag's UI, and just need to complete the previous steps for visualized results.  This will also ensure that our API endpoints are fully compatible with manual testing in the UI which is beneficial for various reasons.  Including testing new edge cases as they come up or the code expands before even making a unit test for simple things (although in the future for maintainability if a new edge case is discovered it should be added to the test suite).  This will allow future students to test our endpoints using the UI, and we imagine this will be particularly helpful for the future teams working on the frontend as they will be able to manually run their API requests and see the JSON response they are getting in one window to manually check their frontend calls.  This should help speed up their debugging process or clear up any uncertainty in behavior beyond the current code documentation if any remains.&lt;br /&gt;
&lt;br /&gt;
===Grades Controller Changes (Improvements based on OSS Project Feedback)===&lt;br /&gt;
* We reduced the complexity of the scores data structure. We started with a quadruple-layered hash map and reduced it to a simple hash map with two branches. This was facilitated &lt;br /&gt;
through the participants' scores model.&lt;br /&gt;
* The complexity fixes were primarily done through modifying '''review_grades'''.&lt;br /&gt;
** Instead of handling '''scores[:teams][team_id][:scores][:avg]''', we changed it to be '''scores[:teams][team_id]'''.&lt;br /&gt;
'''Before:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
team_id = team.id.to_s.to_sym&lt;br /&gt;
      scores[:teams][team_id] ||= { scores: { avg: 0 } }&lt;br /&gt;
&lt;br /&gt;
      # Calculate average score for the team&lt;br /&gt;
      team_scores = participant_scores.map { |s| s[:score].to_f / s[:total_score] * 100 }&lt;br /&gt;
      scores[:teams][team_id][:scores][:avg] = team_scores.sum / team_scores.size&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''After:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
scores[:teams][team_id] ||= 0&lt;br /&gt;
&lt;br /&gt;
      # Calculate average score for the team&lt;br /&gt;
      team_scores = participant_scores.map { |s| s[:score].to_f / s[:total_score] * 100 }&lt;br /&gt;
      scores[:teams][team_id] = team_scores.sum / team_scores.size&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* We changed the logic for '''vector'''&lt;br /&gt;
** We renamed it to: '''filter_scores'''&lt;br /&gt;
'''Before:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    scores[:teams].reject! { |_k, v| v[:scores][:avg].nil? }&lt;br /&gt;
    scores[:teams].map { |_k, v| v[:scores][:avg].to_i }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''After:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    team_scores&lt;br /&gt;
      .compact&lt;br /&gt;
      .map { |team| team.is_a?(Array) ? team[1].to_i : team.to_i }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
** Thanks to the simplification of the scores data structure, the function no longer violates the '''DRY Principle''' and is more readable.&lt;br /&gt;
* We updated the documentation for '''edit''' and '''instructor_review''' in order to make it clear what the functions accomplished, why, and how.&lt;br /&gt;
* We changed the JSON rendering for '''view_team''' and '''view'''. They were previously returning duplicate data within our scores data structure. Since the modification, it is only returning labeled data that is easily accessible without manipulating the hash.&lt;br /&gt;
* We modified the internal data structure usage, only passing the participants or team branch of the scores data structure, instead of passing the previous structure around.&lt;br /&gt;
&lt;br /&gt;
===Future Implementation===&lt;br /&gt;
&lt;br /&gt;
=Team and Prior information=&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;br /&gt;
&lt;br /&gt;
==Previous Iterations==&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=159930</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=159930"/>
		<updated>2024-12-01T20:29:36Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: /* Grades Controller Changes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
===[https://drive.google.com/file/d/1lgFLevdhs7PTFpibxflQfB45nOXW04jA/view?usp=sharing Swagger Video Submission]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents. Additionally, we will be testing the controller with rswag.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor grade_controller.rb, which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
API::V1::GradesController utilizes action-based permissions through action_allowed to provide broader functionality to instructors versus students. With the frontend systems of the Grades Controller relying on heat map systems, view and view_team provide the detailed grading information to populate them (from the student perspective, reviewer identities are kept hidden). The edit method retrieves the relevant assignment to be modified by the frontend view. For accessing reviews, instructor_review is utilized, leading to access of previous reviews or instantiating new ones. Finally, grade changes are saved through the update function, which additionally covers comment feedback.&lt;br /&gt;
&lt;br /&gt;
This controller structure aligns closely with the traditional CRUD operations providing an organized way to handle grade management. The view and view_team actions are for the Read functionality, allowing both instructors and students to access and review grade data based on their roles. The Create aspect is handled in instructor_review, which either retrieves existing reviews or initiates new ones as needed, ensuring that instructors can easily add comments or feedback for an assignment.&lt;br /&gt;
&lt;br /&gt;
The Update action is fulfilled by update, which is responsible for saving new grading data and feedback from instructors. The Delete functionality is not something the grades_controller is responsible for handling.&lt;br /&gt;
&lt;br /&gt;
This CRUD focused approach makes sure that the refactored grade_controller.rb is efficient and easily maintainable, while offering both instructors and students a seamless experience in managing and reviewing assignment grades. The refactor further enhances clarity and accessibility, aiming to make each action intuitive and easily accessible to the relevant users within Expertiza.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's point of view, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's point of view which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's point of view&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
===Rationale for Changes===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
|-&lt;br /&gt;
|Added a new suite of API endpoint tests that are compatible with Rswag and tested our API endpoints thoroughly, additionally added factories for several projects in the system.&lt;br /&gt;
|As with any software change in a large system, testing is extremely important, so we wrote comprehensive tests for our endpoints.  Additionally, since the grades_controller is dependent on many other models (mainly because there is no grades model).  These changes will help future projects by providing factory methods for various models that did not currently have them in the system which should make testing for other groups easier in the future.&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Code Snippet===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Determines if the current user is able to perform :action as specified by the path parameter&lt;br /&gt;
  # If the user has the role of TA or higher they are granted access to all operations beyond view_team&lt;br /&gt;
  # Uses a switch statement for easy maintainability if added functionality is ever needed for students or&lt;br /&gt;
  # additional roles, to add more functionality simply add additional switch cases in the same syntax with&lt;br /&gt;
  # case 'action' and then some boolean check determining if that is allowed or forbidden.&lt;br /&gt;
  # GET /api/v1/grades/:action/action_allowed&lt;br /&gt;
  def action_allowed&lt;br /&gt;
    permitted = case params[:action]&lt;br /&gt;
                when 'view_team'&lt;br /&gt;
                  view_team_allowed?&lt;br /&gt;
                else&lt;br /&gt;
                  user_ta_privileges?&lt;br /&gt;
                end&lt;br /&gt;
    render json: { allowed: permitted }, status: permitted ? :ok : :forbidden&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides the needed functionality of querying needed values from the backend db and returning them to build the&lt;br /&gt;
  # heat map in the frontend from the TA/staff view.  These values are set in the get_data_for_heat_map method&lt;br /&gt;
  # which takes the assignment id as a parameter.&lt;br /&gt;
  # GET /api/v1/grades/:id/view&lt;br /&gt;
  def view&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    render json: { scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                   review_score_count: @review_score_count }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides all relevant data for the student perspective for the heat map page as well as the&lt;br /&gt;
  # needed information to showcase the questionnaires from the student view.  Additionally, handles the removal of user&lt;br /&gt;
  # identification in the reviews within the hide_reviewers_rom_student method.&lt;br /&gt;
  # GET /api/v1/grades/:id/view_team&lt;br /&gt;
  def view_team&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    @scores[:participants] = hide_reviewers_from_student&lt;br /&gt;
    questionnaires = @assignment.questionnaires&lt;br /&gt;
    questions = retrieve_questions(questionnaires, @assignment.id)&lt;br /&gt;
    render json: {scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                  review_score_count: @review_score_count, questions: questions }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Sets information required for editing the grade information, this includes the participant, questions, scores, and&lt;br /&gt;
  # assignment&lt;br /&gt;
  # GET /api/v1/grades/:id/edit&lt;br /&gt;
  def edit&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: {message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot;}, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    questions = list_questions(assignment)&lt;br /&gt;
    scores = review_grades(assignment, questions)&lt;br /&gt;
    render json: {participant: participant, questions: questions, scores: scores, assignment: assignment}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides functionality that handles informing the frontend which controller and action to direct to for instructor&lt;br /&gt;
  # review given the current state of the system.  The intended controller to handle the creation or editing of a review&lt;br /&gt;
  # is the response controller, however this method just determines if a new review must be made based on figuring out&lt;br /&gt;
  # whether or not an associated review_mapping exists from the participant already.  If one does they should go to&lt;br /&gt;
  # Response#edit and if one does not they should go to Response#new.  Only ever returns a status of ok.&lt;br /&gt;
  # GET /api/v1/grades/:id/instructor_review&lt;br /&gt;
  def instructor_review&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: { message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot; }, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    review_mapping = find_participant_review_mapping(participant)&lt;br /&gt;
    if review_mapping.new_record?&lt;br /&gt;
      render json: { controller: 'response', action: 'new', id: review_mapping.map_id,&lt;br /&gt;
                     return: 'instructor'}, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      review = Response.find_by(map_id: review_mapping.map_id)&lt;br /&gt;
      render json: { controller: 'response', action: 'edit', id: review.id, return: 'instructor'}, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Update method for the grade associated with a team, allows an instructor to upgrade a team's grade with a grade&lt;br /&gt;
  # and a comment on their assignment for submission.  The team is then saved with this change in order to be accessed&lt;br /&gt;
  # elsewhere in the code for needed scoring evaluations.  If a failure occurs while saving the team then this will&lt;br /&gt;
  # return a bad_request response complete with a message and the global ERROR_INFO which can be set elsewhere for&lt;br /&gt;
  # further error handling mechanisms&lt;br /&gt;
  # PATCH /api/v1/grades/:participant_id/update/:grade_for_submission&lt;br /&gt;
  def update&lt;br /&gt;
    participant = AssignmentParticipant.find_by(id: params[:participant_id])&lt;br /&gt;
&lt;br /&gt;
    team = participant.team&lt;br /&gt;
    team.grade_for_submission = params[:grade_for_submission]&lt;br /&gt;
    team.comment_for_submission = params[:comment_for_submission]&lt;br /&gt;
    begin&lt;br /&gt;
      team.save&lt;br /&gt;
    rescue StandardError =&amp;gt; e&lt;br /&gt;
      render json: {message: &amp;quot;Error occurred while updating grade for team #{team.id}&amp;quot;,&lt;br /&gt;
                    error: e.message }, status: :bad_request&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: { controller: 'grades', action: 'view_team', id: participant.id}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===CRUD functionality===&lt;br /&gt;
Before we did our refactor and reimplementation the grades_controller contained several unnecessary methods as well as functions vastly beyond the CRUD operations that belong within a controller like this.  The two CRUD operations that are presently in the system for the grades_controller are read and updated.  The read operation is implemented within the view and view_team method to provide the needed information to view the grade heat map.  Then the update functionality is primarily implemented in the needed edit method which supplies information before the update and the update method has been vastly modified from its old implementation where it was not actually saving objects, we have replaced that with a proper update that modifies the grade and comment similarly to how the old save_grade_and_comment_for_submission method used to work.&lt;br /&gt;
===SOLID Principles===&lt;br /&gt;
Overall we strove to meet SOLID guidelines by limiting the scope of the controller back down to its intended core functionality.  This helped satisfy the single responsibility principle by removing additional functionality beyond the intended scope of this class.  We have also significantly cut down on the required helpers needed for these operations through our implementation of a new model participant_scores which helps serve the singular goal of keeping track of score information for questions on an assignment for a given participant. We have also improved the maintainability of the code by making our methods more atomic which should promote extension outside of our methods for new functionality satisfying the Open/Close principle. The remaining three principles did not really apply to this project as the grades_controller has minimal interactions with it's superclass and has no independent model that it controls or is responsible for governing.&lt;br /&gt;
===DRY principle===&lt;br /&gt;
To satisfy the don't repeat yourself principle we sought to make private helper methods to abstract repeated code that was adding complexity to our methods.  One such method is the get_data_for_heat_map method which replaces a substantial amount of what used to be complex and repeated code, which has now been significantly simplified for readability.  Please see the snippet below for the new method, it's primary goal is to set the instance variables of the controller as needed so we can prepare data for the heat map as needed in the front end.  We also relocated complex code that did not aid in the readability into helper methods which have also been refactored, the main goal of this was to promote readability in the main endpoint methods remove unnecessary clutter from the code, and limit code repetition in future modifications by providing modular helper methods for functionality that we believe may need to be repeated in future enhancements such as listing the questions or querying review grades.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Provides data for the heat maps in the view statements&lt;br /&gt;
  def get_data_for_heat_map(id)&lt;br /&gt;
    # Finds the assignment&lt;br /&gt;
    @assignment = Assignment.find(id)&lt;br /&gt;
    # Extracts the questionnaires&lt;br /&gt;
    @questions = filter_questionnaires(@assignment)&lt;br /&gt;
    @scores = review_grades(@assignment, @questions)&lt;br /&gt;
    @review_score_count = @scores[:teams].length # After rejecting nil scores need original length to iterate over hash&lt;br /&gt;
    @averages = vector(@scores)&lt;br /&gt;
    @avg_of_avg = mean(@averages)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Testing Details===&lt;br /&gt;
The test file can be located at:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spec/requests/api/v1/grades_controller_spec.rb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''action_allowed'''&lt;br /&gt;
** Passes in the view action and an assignment we wish to view. Determines if the user has the appropriate permissions to view it.&lt;br /&gt;
*'''view'''&lt;br /&gt;
** Passes in the id of the assignment and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''view_team'''&lt;br /&gt;
** Pasess in the assignment id and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''edit'''&lt;br /&gt;
** Passes in the id of the assignment and expects the participant's id, the same assignment's id, '''questions''', and '''scores'''.&lt;br /&gt;
*'''instructor_review'''&lt;br /&gt;
** Passes in the id of a participant and expects '''controller''', '''action''', the same participant id, and the instructor.&lt;br /&gt;
*'''update'''&lt;br /&gt;
** Passes in a participant id and a body which contains '''grade_for_submission''' (integer) and '''comment_for_submission''' (string). Expects the same grade, comment, '''action''', and participant's id.&lt;br /&gt;
&lt;br /&gt;
'''Rswag UI'''&lt;br /&gt;
[[File:Grades_controller_test_fall_2024.png|700px|An image showing the rswag ui of accepted test results.]]&lt;br /&gt;
=Final project additions=&lt;br /&gt;
==The Problem and Remaining Work==&lt;br /&gt;
While working on our OSS project we ran into substantial difficulties with testing our controller.  The primary reason for this is that the grades_controller is one of the first controller classes in the reimplementation backend that does not have a primary model associated with it.  This is because it does not seem prudent to make a grades model, as scores can be held and tracked as fields in other objects as primitives so this abstraction would not be particularly helpful.  However, this poses an interesting challenge when testing and reimplementing the controller.  Specifically, the dependency on the successful initialization of numerous models throughout the controller including Assignment, Participant, and Team to name a few of the model classes required for operations within the grades_controller for the present create and edit CRUD operations implemented within.  During our OSS project, we were able to slim down the controller and implement more elegant and atomic solutions to the tasks that the original controller was responsible for with some refactoring and reimplementation of various methods.  However, even with these changes, the grades_controller is still dependent on several other classes and their interactions within the system being initialized and in a valid state in order to perform (or test) the required operations.&lt;br /&gt;
&lt;br /&gt;
The primary difficulty in testing our controller as indicated above was this high dependency on other models for correct functionality.  Because of this, we had to construct and instantiate several different models in our test code.  This, in a vacuum, may not be an issue.  However, as the reimplementation backend codebase continues to grow this issue has the potential to become a recurring one where the ultimate result will be several violations of the DRY principle in the testing suite instantiating needed objects inside of controller tests similarly to the way that we had to do this at the start.  In the current codebase, the only models containing factory code are student_task, join_team_request, bookmark, and user, making this substantially shy of the thirty-six models currently residing within the reimplementation_backend repository.  We will seek to change this in order to limit the likelihood of DRY violations in the test suite moving forward to improve code maintainability and consistency.  This should also directly benefit future students who will not need to struggle with implementing testing for dependent controllers.  It should also make future refactors much less painful in terms of changing models breaking test cases, if the models are built in factories these issues may be rectified for all failing locations within the factory class rather than requiring the modification of several test files in the system.&lt;br /&gt;
&lt;br /&gt;
==Our solution==&lt;br /&gt;
Our solution to improving our OSS submission and the overall codebase is four-pronged.  This includes expanding the factory suite to include many additional models.  Our second plan is to improve our test cases and our overall test plan to be more comprehensive of all branches present in our code to conduct more thorough testing using our new factories.  Our third change will be to modify the seeding files for the db in order to facilitate manual testing with RSwag.  Finally our fourth goal for the project is to improve our RSwag UI by implementing the previous three steps and then ensuring that manual testing capability is achieved and correct.&lt;br /&gt;
===Expanded Factory Suite===&lt;br /&gt;
For our final project we are seeking to improve the code base by expanding the factory suite to include factories for most of the 37 models present in the reimplementation backend repository. The rationale behind this decision is to improve the testing capabilities of all controllers either currently in the system or ones that will be added. As the code base grows, we expect an increased interdependency of the controllers on the model classes. Without factory classes, this would result in an opportunity for several DRY violations in the test suite. This hinders the maintainability of the code base and as small changes in the models could break the entire test suite and would need to be solved individually in every test case; however, with factories, we would only need to fix the code within the factories to reflect the new code structure and the test cases will remain largely unchanged. We would also suggest that factories be continuously updated as new models are added so that it aids in future maintainability.&lt;br /&gt;
&lt;br /&gt;
===Improved Test Plan===&lt;br /&gt;
* action_allowed&lt;br /&gt;
** If the user is a TA or higher, then a successful status will be returned for all actions.&lt;br /&gt;
** If the user is a student and requests to view their team then, then a successful status will be returned.&lt;br /&gt;
** Otherwise, a status of prohibited is rendered regardless of the action.&lt;br /&gt;
* view&lt;br /&gt;
** A successful status, the scores, the assignment, the averages, the meta average, and the review score count are all rendered so that the heat map can be displayed. &lt;br /&gt;
* view_team&lt;br /&gt;
** A successful status, the scores, the assignment with filtered questionnaire authors , the averages, the meta average, and the review score count are all rendered so that the heat map can be displayed. &lt;br /&gt;
* edit&lt;br /&gt;
** If the assignment participant is not found, then a not found status is rendered.&lt;br /&gt;
** Otherwise, a successful status, the participant, the questions, the scores, and the assignment are all rendered.&lt;br /&gt;
* instructor_review&lt;br /&gt;
** If the assignment participant is not found, then a not found status is rendered.&lt;br /&gt;
** If the instructor review is new then a response is rendered to tell the front end to go to the response controllers new action with the reviews mapping's id.&lt;br /&gt;
** Otherwise, a response is rendered to tell the front end to go to the response controller's edit action with the review's id.&lt;br /&gt;
* update&lt;br /&gt;
** If the team cannot be saved, then a bad request status is rendered.&lt;br /&gt;
** Otherwise, a response is rendered to tell the front end to go to the grades controller's view team action with the participant's id.&lt;br /&gt;
====Flow Chart====&lt;br /&gt;
[[File:Decision_tree.png|700px|An image showing flow chart]]&lt;br /&gt;
&lt;br /&gt;
===Modified db seeding===&lt;br /&gt;
Currently the file '''seeds.rb''' contains only an institution and admin user. To streamline testing and set up appropriate models, we will make sure the file contains the following:&lt;br /&gt;
* An assignment instance&lt;br /&gt;
* A participant instance&lt;br /&gt;
* A team instance&lt;br /&gt;
* An instructor instance&lt;br /&gt;
To perform testing for the API endpoints, these are the minimum model instances required. The goal of this change is to make sure we can handle manually testing the grades controller with the rswag UI. This is specifically for the reimplementation of the backend. There is an absence of several necessary POST API endpoints implementing CREATE operations. Without these seeded into the database, we would need to cover more implementation on endpoints.&lt;br /&gt;
&lt;br /&gt;
===Functional RSwagUI visualizations and manual testing capability===&lt;br /&gt;
Currently, we have the endpoint visualizations set up on RSwag's UI, and just need to complete the previous steps for visualized results.  This will also ensure that our API endpoints are fully compatible with manual testing in the UI which is beneficial for various reasons.  Including testing new edge cases as they come up or the code expands before even making a unit test for simple things (although in the future for maintainability if a new edge case is discovered it should be added to the test suite).  This will allow future students to test our endpoints using the UI, and we imagine this will be particularly helpful for the future teams working on the frontend as they will be able to manually run their API requests and see the JSON response they are getting in one window to manually check their frontend calls.  This should help speed up their debugging process or clear up any uncertainty in behavior beyond the current code documentation if any remains.&lt;br /&gt;
&lt;br /&gt;
===Grades Controller Changes (Improvements based on OSS Project Feedback)===&lt;br /&gt;
* We reduced the complexity of the scores data structure. We started with a quadruple-layered hash map and reduced it to a simple hash map with two branches. This was facilitated &lt;br /&gt;
through the participants' scores model.&lt;br /&gt;
* The complexity fixes were primarily done through modifying '''review_grades'''.&lt;br /&gt;
** Instead of handling '''scores[:teams][team_id][:scores][:avg]''', we changed it to be '''scores[:teams][team_id]'''.&lt;br /&gt;
* We changed the logic for '''vector'''&lt;br /&gt;
** We renamed it to: '''filter_scores'''&lt;br /&gt;
** Thanks to the simplification of the scores data structure, the function no longer violates the '''DRY Principle''' and is more readable.&lt;br /&gt;
* We updated the documentation for '''edit''' and '''instructor_review''' in order to make it clear what the functions accomplished, why, and how.&lt;br /&gt;
* We changed the JSON rendering for '''view_team''' and '''view'''. They were previously returning duplicate data within our scores data structure. Since the modification, it is only returning labeled data that is easily accessible without manipulating the hash.&lt;br /&gt;
* We modified the internal data structure usage, only passing the participants or team branch of the scores data structure, instead of passing the previous structure around.&lt;br /&gt;
&lt;br /&gt;
===Future Implementation===&lt;br /&gt;
&lt;br /&gt;
=Team and Prior information=&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;br /&gt;
&lt;br /&gt;
==Previous Iterations==&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=159924</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=159924"/>
		<updated>2024-12-01T20:15:24Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: /* Final project additions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
===[https://drive.google.com/file/d/1lgFLevdhs7PTFpibxflQfB45nOXW04jA/view?usp=sharing Swagger Video Submission]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents. Additionally, we will be testing the controller with rswag.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor grade_controller.rb, which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
API::V1::GradesController utilizes action-based permissions through action_allowed to provide broader functionality to instructors versus students. With the frontend systems of the Grades Controller relying on heat map systems, view and view_team provide the detailed grading information to populate them (from the student perspective, reviewer identities are kept hidden). The edit method retrieves the relevant assignment to be modified by the frontend view. For accessing reviews, instructor_review is utilized, leading to access of previous reviews or instantiating new ones. Finally, grade changes are saved through the update function, which additionally covers comment feedback.&lt;br /&gt;
&lt;br /&gt;
This controller structure aligns closely with the traditional CRUD operations providing an organized way to handle grade management. The view and view_team actions are for the Read functionality, allowing both instructors and students to access and review grade data based on their roles. The Create aspect is handled in instructor_review, which either retrieves existing reviews or initiates new ones as needed, ensuring that instructors can easily add comments or feedback for an assignment.&lt;br /&gt;
&lt;br /&gt;
The Update action is fulfilled by update, which is responsible for saving new grading data and feedback from instructors. The Delete functionality is not something the grades_controller is responsible for handling.&lt;br /&gt;
&lt;br /&gt;
This CRUD focused approach makes sure that the refactored grade_controller.rb is efficient and easily maintainable, while offering both instructors and students a seamless experience in managing and reviewing assignment grades. The refactor further enhances clarity and accessibility, aiming to make each action intuitive and easily accessible to the relevant users within Expertiza.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's point of view, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's point of view which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's point of view&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
===Rationale for Changes===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
|-&lt;br /&gt;
|Added a new suite of API endpoint tests that are compatible with Rswag and tested our API endpoints thoroughly, additionally added factories for several projects in the system.&lt;br /&gt;
|As with any software change in a large system, testing is extremely important, so we wrote comprehensive tests for our endpoints.  Additionally, since the grades_controller is dependent on many other models (mainly because there is no grades model).  These changes will help future projects by providing factory methods for various models that did not currently have them in the system which should make testing for other groups easier in the future.&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Code Snippet===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Determines if the current user is able to perform :action as specified by the path parameter&lt;br /&gt;
  # If the user has the role of TA or higher they are granted access to all operations beyond view_team&lt;br /&gt;
  # Uses a switch statement for easy maintainability if added functionality is ever needed for students or&lt;br /&gt;
  # additional roles, to add more functionality simply add additional switch cases in the same syntax with&lt;br /&gt;
  # case 'action' and then some boolean check determining if that is allowed or forbidden.&lt;br /&gt;
  # GET /api/v1/grades/:action/action_allowed&lt;br /&gt;
  def action_allowed&lt;br /&gt;
    permitted = case params[:action]&lt;br /&gt;
                when 'view_team'&lt;br /&gt;
                  view_team_allowed?&lt;br /&gt;
                else&lt;br /&gt;
                  user_ta_privileges?&lt;br /&gt;
                end&lt;br /&gt;
    render json: { allowed: permitted }, status: permitted ? :ok : :forbidden&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides the needed functionality of querying needed values from the backend db and returning them to build the&lt;br /&gt;
  # heat map in the frontend from the TA/staff view.  These values are set in the get_data_for_heat_map method&lt;br /&gt;
  # which takes the assignment id as a parameter.&lt;br /&gt;
  # GET /api/v1/grades/:id/view&lt;br /&gt;
  def view&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    render json: { scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                   review_score_count: @review_score_count }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides all relevant data for the student perspective for the heat map page as well as the&lt;br /&gt;
  # needed information to showcase the questionnaires from the student view.  Additionally, handles the removal of user&lt;br /&gt;
  # identification in the reviews within the hide_reviewers_rom_student method.&lt;br /&gt;
  # GET /api/v1/grades/:id/view_team&lt;br /&gt;
  def view_team&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    @scores[:participants] = hide_reviewers_from_student&lt;br /&gt;
    questionnaires = @assignment.questionnaires&lt;br /&gt;
    questions = retrieve_questions(questionnaires, @assignment.id)&lt;br /&gt;
    render json: {scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                  review_score_count: @review_score_count, questions: questions }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Sets information required for editing the grade information, this includes the participant, questions, scores, and&lt;br /&gt;
  # assignment&lt;br /&gt;
  # GET /api/v1/grades/:id/edit&lt;br /&gt;
  def edit&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: {message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot;}, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    questions = list_questions(assignment)&lt;br /&gt;
    scores = review_grades(assignment, questions)&lt;br /&gt;
    render json: {participant: participant, questions: questions, scores: scores, assignment: assignment}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides functionality that handles informing the frontend which controller and action to direct to for instructor&lt;br /&gt;
  # review given the current state of the system.  The intended controller to handle the creation or editing of a review&lt;br /&gt;
  # is the response controller, however this method just determines if a new review must be made based on figuring out&lt;br /&gt;
  # whether or not an associated review_mapping exists from the participant already.  If one does they should go to&lt;br /&gt;
  # Response#edit and if one does not they should go to Response#new.  Only ever returns a status of ok.&lt;br /&gt;
  # GET /api/v1/grades/:id/instructor_review&lt;br /&gt;
  def instructor_review&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: { message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot; }, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    review_mapping = find_participant_review_mapping(participant)&lt;br /&gt;
    if review_mapping.new_record?&lt;br /&gt;
      render json: { controller: 'response', action: 'new', id: review_mapping.map_id,&lt;br /&gt;
                     return: 'instructor'}, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      review = Response.find_by(map_id: review_mapping.map_id)&lt;br /&gt;
      render json: { controller: 'response', action: 'edit', id: review.id, return: 'instructor'}, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Update method for the grade associated with a team, allows an instructor to upgrade a team's grade with a grade&lt;br /&gt;
  # and a comment on their assignment for submission.  The team is then saved with this change in order to be accessed&lt;br /&gt;
  # elsewhere in the code for needed scoring evaluations.  If a failure occurs while saving the team then this will&lt;br /&gt;
  # return a bad_request response complete with a message and the global ERROR_INFO which can be set elsewhere for&lt;br /&gt;
  # further error handling mechanisms&lt;br /&gt;
  # PATCH /api/v1/grades/:participant_id/update/:grade_for_submission&lt;br /&gt;
  def update&lt;br /&gt;
    participant = AssignmentParticipant.find_by(id: params[:participant_id])&lt;br /&gt;
&lt;br /&gt;
    team = participant.team&lt;br /&gt;
    team.grade_for_submission = params[:grade_for_submission]&lt;br /&gt;
    team.comment_for_submission = params[:comment_for_submission]&lt;br /&gt;
    begin&lt;br /&gt;
      team.save&lt;br /&gt;
    rescue StandardError =&amp;gt; e&lt;br /&gt;
      render json: {message: &amp;quot;Error occurred while updating grade for team #{team.id}&amp;quot;,&lt;br /&gt;
                    error: e.message }, status: :bad_request&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: { controller: 'grades', action: 'view_team', id: participant.id}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===CRUD functionality===&lt;br /&gt;
Before we did our refactor and reimplementation the grades_controller contained several unnecessary methods as well as functions vastly beyond the CRUD operations that belong within a controller like this.  The two CRUD operations that are presently in the system for the grades_controller are read and updated.  The read operation is implemented within the view and view_team method to provide the needed information to view the grade heat map.  Then the update functionality is primarily implemented in the needed edit method which supplies information before the update and the update method has been vastly modified from its old implementation where it was not actually saving objects, we have replaced that with a proper update that modifies the grade and comment similarly to how the old save_grade_and_comment_for_submission method used to work.&lt;br /&gt;
===SOLID Principles===&lt;br /&gt;
Overall we strove to meet SOLID guidelines by limiting the scope of the controller back down to its intended core functionality.  This helped satisfy the single responsibility principle by removing additional functionality beyond the intended scope of this class.  We have also significantly cut down on the required helpers needed for these operations through our implementation of a new model participant_scores which helps serve the singular goal of keeping track of score information for questions on an assignment for a given participant. We have also improved the maintainability of the code by making our methods more atomic which should promote extension outside of our methods for new functionality satisfying the Open/Close principle. The remaining three principles did not really apply to this project as the grades_controller has minimal interactions with it's superclass and has no independent model that it controls or is responsible for governing.&lt;br /&gt;
===DRY principle===&lt;br /&gt;
To satisfy the don't repeat yourself principle we sought to make private helper methods to abstract repeated code that was adding complexity to our methods.  One such method is the get_data_for_heat_map method which replaces a substantial amount of what used to be complex and repeated code, which has now been significantly simplified for readability.  Please see the snippet below for the new method, it's primary goal is to set the instance variables of the controller as needed so we can prepare data for the heat map as needed in the front end.  We also relocated complex code that did not aid in the readability into helper methods which have also been refactored, the main goal of this was to promote readability in the main endpoint methods remove unnecessary clutter from the code, and limit code repetition in future modifications by providing modular helper methods for functionality that we believe may need to be repeated in future enhancements such as listing the questions or querying review grades.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Provides data for the heat maps in the view statements&lt;br /&gt;
  def get_data_for_heat_map(id)&lt;br /&gt;
    # Finds the assignment&lt;br /&gt;
    @assignment = Assignment.find(id)&lt;br /&gt;
    # Extracts the questionnaires&lt;br /&gt;
    @questions = filter_questionnaires(@assignment)&lt;br /&gt;
    @scores = review_grades(@assignment, @questions)&lt;br /&gt;
    @review_score_count = @scores[:teams].length # After rejecting nil scores need original length to iterate over hash&lt;br /&gt;
    @averages = vector(@scores)&lt;br /&gt;
    @avg_of_avg = mean(@averages)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Testing Details===&lt;br /&gt;
The test file can be located at:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spec/requests/api/v1/grades_controller_spec.rb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''action_allowed'''&lt;br /&gt;
** Passes in the view action and an assignment we wish to view. Determines if the user has the appropriate permissions to view it.&lt;br /&gt;
*'''view'''&lt;br /&gt;
** Passes in the id of the assignment and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''view_team'''&lt;br /&gt;
** Pasess in the assignment id and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''edit'''&lt;br /&gt;
** Passes in the id of the assignment and expects the participant's id, the same assignment's id, '''questions''', and '''scores'''.&lt;br /&gt;
*'''instructor_review'''&lt;br /&gt;
** Passes in the id of a participant and expects '''controller''', '''action''', the same participant id, and the instructor.&lt;br /&gt;
*'''update'''&lt;br /&gt;
** Passes in a participant id and a body which contains '''grade_for_submission''' (integer) and '''comment_for_submission''' (string). Expects the same grade, comment, '''action''', and participant's id.&lt;br /&gt;
&lt;br /&gt;
'''Rswag UI'''&lt;br /&gt;
[[File:Grades_controller_test_fall_2024.png|700px|An image showing the rswag ui of accepted test results.]]&lt;br /&gt;
=Final project additions=&lt;br /&gt;
==The Problem and Remaining Work==&lt;br /&gt;
While working on our OSS project we ran into substantial difficulties with testing our controller.  The primary reason for this is that the grades_controller is one of the first controller classes in the reimplementation backend that does not have a primary model associated with it.  This is because it does not seem prudent to make a grades model, as scores can be held and tracked as fields in other objects as primitives so this abstraction would not be particularly helpful.  However, this poses an interesting challenge when testing and reimplementing the controller.  Specifically, the dependency on the successful initialization of numerous models throughout the controller including Assignment, Participant, and Team to name a few of the model classes required for operations within the grades_controller for the present create and edit CRUD operations implemented within.  During our OSS project, we were able to slim down the controller and implement more elegant and atomic solutions to the tasks that the original controller was responsible for with some refactoring and reimplementation of various methods.  However, even with these changes, the grades_controller is still dependent on several other classes and their interactions within the system being initialized and in a valid state in order to perform (or test) the required operations.&lt;br /&gt;
&lt;br /&gt;
The primary difficulty in testing our controller as indicated above was this high dependency on other models for correct functionality.  Because of this, we had to construct and instantiate several different models in our test code.  This, in a vacuum, may not be an issue.  However, as the reimplementation backend codebase continues to grow this issue has the potential to become a recurring one where the ultimate result will be several violations of the DRY principle in the testing suite instantiating needed objects inside of controller tests similarly to the way that we had to do this at the start.  In the current codebase, the only models containing factory code are student_task, join_team_request, bookmark, and user, making this substantially shy of the thirty-six models currently residing within the reimplementation_backend repository.  We will seek to change this in order to limit the likelihood of DRY violations in the test suite moving forward to improve code maintainability and consistency.  This should also directly benefit future students who will not need to struggle with implementing testing for dependent controllers.  It should also make future refactors much less painful in terms of changing models breaking test cases, if the models are built in factories these issues may be rectified for all failing locations within the factory class rather than requiring the modification of several test files in the system.&lt;br /&gt;
&lt;br /&gt;
==Our solution==&lt;br /&gt;
Our solution to improving our OSS submission and the overall codebase is four-pronged.  This includes expanding the factory suite to include many additional models.  Our second plan is to improve our test cases and our overall test plan to be more comprehensive of all branches present in our code to conduct more thorough testing using our new factories.  Our third change will be to modify the seeding files for the db in order to facilitate manual testing with RSwag.  Finally our fourth goal for the project is to improve our RSwag UI by implementing the previous three steps and then ensuring that manual testing capability is achieved and correct.&lt;br /&gt;
===Expanded Factory Suite===&lt;br /&gt;
For our final project we are seeking to improve the code base by expanding the factory suite to include factories for most of the 37 models present in the reimplementation backend repository. The rationale behind this decision is to improve the testing capabilities of all controllers either currently in the system or ones that will be added. As the code base grows, we expect an increased interdependency of the controllers on the model classes. Without factory classes, this would result in an opportunity for several DRY violations in the test suite. This hinders the maintainability of the code base and as small changes in the models could break the entire test suite and would need to be solved individually in every test case; however, with factories, we would only need to fix the code within the factories to reflect the new code structure and the test cases will remain largely unchanged. We would also suggest that factories be continuously updated as new models are added so that it aids in future maintainability.&lt;br /&gt;
&lt;br /&gt;
===Improved Test Plan===&lt;br /&gt;
* action_allowed&lt;br /&gt;
** If the user is a TA or higher, then a successful status will be returned for all actions.&lt;br /&gt;
** If the user is a student and requests to view their team then, then a successful status will be returned.&lt;br /&gt;
** Otherwise, a status of prohibited is rendered regardless of the action.&lt;br /&gt;
* view&lt;br /&gt;
** A successful status, the scores, the assignment, the averages, the meta average, and the review score count are all rendered so that the heat map can be displayed. &lt;br /&gt;
* view_team&lt;br /&gt;
** A successful status, the scores, the assignment with filtered questionnaire authors , the averages, the meta average, and the review score count are all rendered so that the heat map can be displayed. &lt;br /&gt;
* edit&lt;br /&gt;
** If the assignment participant is not found, then a not found status is rendered.&lt;br /&gt;
** Otherwise, a successful status, the participant, the questions, the scores, and the assignment are all rendered.&lt;br /&gt;
* instructor_review&lt;br /&gt;
** If the assignment participant is not found, then a not found status is rendered.&lt;br /&gt;
** If the instructor review is new then a response is rendered to tell the front end to go to the response controllers new action with the reviews mapping's id.&lt;br /&gt;
** Otherwise, a response is rendered to tell the front end to go to the response controller's edit action with the review's id.&lt;br /&gt;
* update&lt;br /&gt;
** If the team cannot be saved, then a bad request status is rendered.&lt;br /&gt;
** Otherwise, a response is rendered to tell the front end to go to the grades controller's view team action with the participant's id.&lt;br /&gt;
====Flow Chart====&lt;br /&gt;
[[File:Decision_tree.png|700px|An image showing flow chart]]&lt;br /&gt;
&lt;br /&gt;
===Modified db seeding===&lt;br /&gt;
Currently the file '''seeds.rb''' contains only an institution and admin user. To streamline testing and set up appropriate models, we will make sure the file contains the following:&lt;br /&gt;
* An assignment instance&lt;br /&gt;
* A participant instance&lt;br /&gt;
* A team instance&lt;br /&gt;
* An instructor instance&lt;br /&gt;
To perform testing for the API endpoints, these are the minimum model instances required. The goal of this change is to make sure we can handle manually testing the grades controller with the rswag UI. This is specifically for the reimplementation of the backend. There is an absence of several necessary POST API endpoints implementing CREATE operations. Without these seeded into the database, we would need to cover more implementation on endpoints.&lt;br /&gt;
&lt;br /&gt;
===Functional RSwagUI visualizations and manual testing capability===&lt;br /&gt;
Currently, we have the endpoint visualizations set up on RSwag's UI, and just need to complete the previous steps for visualized results.  This will also ensure that our API endpoints are fully compatible with manual testing in the UI which is beneficial for various reasons.  Including testing new edge cases as they come up or the code expands before even making a unit test for simple things (although in the future for maintainability if a new edge case is discovered it should be added to the test suite).  This will allow future students to test our endpoints using the UI, and we imagine this will be particularly helpful for the future teams working on the frontend as they will be able to manually run their API requests and see the JSON response they are getting in one window to manually check their frontend calls.  This should help speed up their debugging process or clear up any uncertainty in behavior beyond the current code documentation if any remains.&lt;br /&gt;
&lt;br /&gt;
===Grades Controller Changes===&lt;br /&gt;
* Reduced the complexity of the scores data structure.&lt;br /&gt;
&lt;br /&gt;
===Future Implementation===&lt;br /&gt;
&lt;br /&gt;
=Team and Prior information=&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;br /&gt;
&lt;br /&gt;
==Previous Iterations==&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158758</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158758"/>
		<updated>2024-11-10T20:36:52Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: /* Modified db seeding */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
===[https://drive.google.com/file/d/1lgFLevdhs7PTFpibxflQfB45nOXW04jA/view?usp=sharing Swagger Video Submission]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents. Additionally, we will be testing the controller with rswag.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor grade_controller.rb, which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
API::V1::GradesController utilizes action-based permissions through action_allowed to provide broader functionality to instructors versus students. With the frontend systems of the Grades Controller relying on heat map systems, view and view_team provide the detailed grading information to populate them (from the student perspective, reviewer identities are kept hidden). The edit method retrieves the relevant assignment to be modified by the frontend view. For accessing reviews, instructor_review is utilized, leading to access of previous reviews or instantiating new ones. Finally, grade changes are saved through the update function, which additionally covers comment feedback.&lt;br /&gt;
&lt;br /&gt;
This controller structure aligns closely with the traditional CRUD operations providing an organized way to handle grade management. The view and view_team actions are for the Read functionality, allowing both instructors and students to access and review grade data based on their roles. The Create aspect is handled in instructor_review, which either retrieves existing reviews or initiates new ones as needed, ensuring that instructors can easily add comments or feedback for an assignment.&lt;br /&gt;
&lt;br /&gt;
The Update action is fulfilled by update, which is responsible for saving new grading data and feedback from instructors. The Delete functionality is not something the grades_controller is responsible for handling.&lt;br /&gt;
&lt;br /&gt;
This CRUD focused approach makes sure that the refactored grade_controller.rb is efficient and easily maintainable, while offering both instructors and students a seamless experience in managing and reviewing assignment grades. The refactor further enhances clarity and accessibility, aiming to make each action intuitive and easily accessible to the relevant users within Expertiza.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's point of view, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's point of view which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's point of view&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
===Rationale for Changes===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
|-&lt;br /&gt;
|Added a new suite of API endpoint tests that are compatible with Rswag and tested our API endpoints thoroughly, additionally added factories for several projects in the system.&lt;br /&gt;
|As with any software change in a large system, testing is extremely important, so we wrote comprehensive tests for our endpoints.  Additionally, since the grades_controller is dependent on many other models (mainly because there is no grades model).  These changes will help future projects by providing factory methods for various models that did not currently have them in the system which should make testing for other groups easier in the future.&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Code Snippet===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Determines if the current user is able to perform :action as specified by the path parameter&lt;br /&gt;
  # If the user has the role of TA or higher they are granted access to all operations beyond view_team&lt;br /&gt;
  # Uses a switch statement for easy maintainability if added functionality is ever needed for students or&lt;br /&gt;
  # additional roles, to add more functionality simply add additional switch cases in the same syntax with&lt;br /&gt;
  # case 'action' and then some boolean check determining if that is allowed or forbidden.&lt;br /&gt;
  # GET /api/v1/grades/:action/action_allowed&lt;br /&gt;
  def action_allowed&lt;br /&gt;
    permitted = case params[:action]&lt;br /&gt;
                when 'view_team'&lt;br /&gt;
                  view_team_allowed?&lt;br /&gt;
                else&lt;br /&gt;
                  user_ta_privileges?&lt;br /&gt;
                end&lt;br /&gt;
    render json: { allowed: permitted }, status: permitted ? :ok : :forbidden&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides the needed functionality of querying needed values from the backend db and returning them to build the&lt;br /&gt;
  # heat map in the frontend from the TA/staff view.  These values are set in the get_data_for_heat_map method&lt;br /&gt;
  # which takes the assignment id as a parameter.&lt;br /&gt;
  # GET /api/v1/grades/:id/view&lt;br /&gt;
  def view&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    render json: { scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                   review_score_count: @review_score_count }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides all relevant data for the student perspective for the heat map page as well as the&lt;br /&gt;
  # needed information to showcase the questionnaires from the student view.  Additionally, handles the removal of user&lt;br /&gt;
  # identification in the reviews within the hide_reviewers_rom_student method.&lt;br /&gt;
  # GET /api/v1/grades/:id/view_team&lt;br /&gt;
  def view_team&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    @scores[:participants] = hide_reviewers_from_student&lt;br /&gt;
    questionnaires = @assignment.questionnaires&lt;br /&gt;
    questions = retrieve_questions(questionnaires, @assignment.id)&lt;br /&gt;
    render json: {scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                  review_score_count: @review_score_count, questions: questions }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Sets information required for editing the grade information, this includes the participant, questions, scores, and&lt;br /&gt;
  # assignment&lt;br /&gt;
  # GET /api/v1/grades/:id/edit&lt;br /&gt;
  def edit&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: {message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot;}, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    questions = list_questions(assignment)&lt;br /&gt;
    scores = review_grades(assignment, questions)&lt;br /&gt;
    render json: {participant: participant, questions: questions, scores: scores, assignment: assignment}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides functionality that handles informing the frontend which controller and action to direct to for instructor&lt;br /&gt;
  # review given the current state of the system.  The intended controller to handle the creation or editing of a review&lt;br /&gt;
  # is the response controller, however this method just determines if a new review must be made based on figuring out&lt;br /&gt;
  # whether or not an associated review_mapping exists from the participant already.  If one does they should go to&lt;br /&gt;
  # Response#edit and if one does not they should go to Response#new.  Only ever returns a status of ok.&lt;br /&gt;
  # GET /api/v1/grades/:id/instructor_review&lt;br /&gt;
  def instructor_review&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: { message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot; }, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    review_mapping = find_participant_review_mapping(participant)&lt;br /&gt;
    if review_mapping.new_record?&lt;br /&gt;
      render json: { controller: 'response', action: 'new', id: review_mapping.map_id,&lt;br /&gt;
                     return: 'instructor'}, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      review = Response.find_by(map_id: review_mapping.map_id)&lt;br /&gt;
      render json: { controller: 'response', action: 'edit', id: review.id, return: 'instructor'}, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Update method for the grade associated with a team, allows an instructor to upgrade a team's grade with a grade&lt;br /&gt;
  # and a comment on their assignment for submission.  The team is then saved with this change in order to be accessed&lt;br /&gt;
  # elsewhere in the code for needed scoring evaluations.  If a failure occurs while saving the team then this will&lt;br /&gt;
  # return a bad_request response complete with a message and the global ERROR_INFO which can be set elsewhere for&lt;br /&gt;
  # further error handling mechanisms&lt;br /&gt;
  # PATCH /api/v1/grades/:participant_id/update/:grade_for_submission&lt;br /&gt;
  def update&lt;br /&gt;
    participant = AssignmentParticipant.find_by(id: params[:participant_id])&lt;br /&gt;
&lt;br /&gt;
    team = participant.team&lt;br /&gt;
    team.grade_for_submission = params[:grade_for_submission]&lt;br /&gt;
    team.comment_for_submission = params[:comment_for_submission]&lt;br /&gt;
    begin&lt;br /&gt;
      team.save&lt;br /&gt;
    rescue StandardError =&amp;gt; e&lt;br /&gt;
      render json: {message: &amp;quot;Error occurred while updating grade for team #{team.id}&amp;quot;,&lt;br /&gt;
                    error: e.message }, status: :bad_request&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: { controller: 'grades', action: 'view_team', id: participant.id}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===CRUD functionality===&lt;br /&gt;
Before we did our refactor and reimplementation the grades_controller contained several unnecessary methods as well as functions vastly beyond the CRUD operations that belong within a controller like this.  The two CRUD operations that are presently in the system for the grades_controller are read and updated.  The read operation is implemented within the view and view_team method to provide the needed information to view the grade heat map.  Then the update functionality is primarily implemented in the needed edit method which supplies information before the update and the update method has been vastly modified from its old implementation where it was not actually saving objects, we have replaced that with a proper update that modifies the grade and comment similarly to how the old save_grade_and_comment_for_submission method used to work.&lt;br /&gt;
===SOLID Principles===&lt;br /&gt;
Overall we strove to meet SOLID guidelines by limiting the scope of the controller back down to its intended core functionality.  This helped satisfy the single responsibility principle by removing additional functionality beyond the intended scope of this class.  We have also significantly cut down on the required helpers needed for these operations through our implementation of a new model participant_scores which helps serve the singular goal of keeping track of score information for questions on an assignment for a given participant. We have also improved the maintainability of the code by making our methods more atomic which should promote extension outside of our methods for new functionality satisfying the Open/Close principle. The remaining three principles did not really apply to this project as the grades_controller has minimal interactions with it's superclass and has no independent model that it controls or is responsible for governing.&lt;br /&gt;
===DRY principle===&lt;br /&gt;
To satisfy the don't repeat yourself principle we sought to make private helper methods to abstract repeated code that was adding complexity to our methods.  One such method is the get_data_for_heat_map method which replaces a substantial amount of what used to be complex and repeated code, which has now been significantly simplified for readability.  Please see the snippet below for the new method, it's primary goal is to set the instance variables of the controller as needed so we can prepare data for the heat map as needed in the front end.  We also relocated complex code that did not aid in the readability into helper methods which have also been refactored, the main goal of this was to promote readability in the main endpoint methods remove unnecessary clutter from the code, and limit code repetition in future modifications by providing modular helper methods for functionality that we believe may need to be repeated in future enhancements such as listing the questions or querying review grades.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Provides data for the heat maps in the view statements&lt;br /&gt;
  def get_data_for_heat_map(id)&lt;br /&gt;
    # Finds the assignment&lt;br /&gt;
    @assignment = Assignment.find(id)&lt;br /&gt;
    # Extracts the questionnaires&lt;br /&gt;
    @questions = filter_questionnaires(@assignment)&lt;br /&gt;
    @scores = review_grades(@assignment, @questions)&lt;br /&gt;
    @review_score_count = @scores[:teams].length # After rejecting nil scores need original length to iterate over hash&lt;br /&gt;
    @averages = vector(@scores)&lt;br /&gt;
    @avg_of_avg = mean(@averages)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Testing Details===&lt;br /&gt;
The test file can be located at:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spec/requests/api/v1/grades_controller_spec.rb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''action_allowed'''&lt;br /&gt;
** Passes in the view action and an assignment we wish to view. Determines if the user has the appropriate permissions to view it.&lt;br /&gt;
*'''view'''&lt;br /&gt;
** Passes in the id of the assignment and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''view_team'''&lt;br /&gt;
** Pasess in the assignment id and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''edit'''&lt;br /&gt;
** Passes in the id of the assignment and expects the participant's id, the same assignment's id, '''questions''', and '''scores'''.&lt;br /&gt;
*'''instructor_review'''&lt;br /&gt;
** Passes in the id of a participant and expects '''controller''', '''action''', the same participant id, and the instructor.&lt;br /&gt;
*'''update'''&lt;br /&gt;
** Passes in a participant id and a body which contains '''grade_for_submission''' (integer) and '''comment_for_submission''' (string). Expects the same grade, comment, '''action''', and participant's id.&lt;br /&gt;
&lt;br /&gt;
'''Rswag UI'''&lt;br /&gt;
[[File:Grades_controller_test_fall_2024.png|700px|An image showing the rswag ui of accepted test results.]]&lt;br /&gt;
=Final project additions=&lt;br /&gt;
==The Problem and Remaining Work==&lt;br /&gt;
While working on our OSS project we ran into substantial difficulties with testing our controller.  The primary reason for this is that the grades_controller is one of the first controller classes in the reimplementation backend that does not have a primary model associated with it.  This is because it does not seem prudent to make a grades model, as scores can be held and tracked as fields in other objects as primitives so this abstraction would not be particularly helpful.  However, this poses an interesting challenge when testing and reimplementing the controller.  Specifically, the dependency on the successful initialization of numerous models throughout the controller including Assignment, Participant, and Team to name a few of the model classes required for operations within the grades_controller for the present create and edit CRUD operations implemented within.  During our OSS project, we were able to slim down the controller and implement more elegant and atomic solutions to the tasks that the original controller was responsible for with some refactoring and reimplementation of various methods.  However, even with these changes, the grades_controller is still dependent on several other classes and their interactions within the system being initialized and in a valid state in order to perform (or test) the required operations.&lt;br /&gt;
&lt;br /&gt;
The primary difficulty in testing our controller as indicated above was this high dependency on other models for correct functionality.  Because of this, we had to construct and instantiate several different models in our test code.  This, in a vacuum, may not be an issue.  However, as the reimplementation backend codebase continues to grow this issue has the potential to become a recurring one where the ultimate result will be several violations of the DRY principle in the testing suite instantiating needed objects inside of controller tests similarly to the way that we had to do this at the start.  In the current codebase, the only models containing factory code are student_task, join_team_request, bookmark, and user, making this substantially shy of the thirty-six models currently residing within the reimplementation_backend repository.  We will seek to change this in order to limit the likelihood of DRY violations in the test suite moving forward to improve code maintainability and consistency.  &lt;br /&gt;
==Our solution==&lt;br /&gt;
Our solution to improving our OSS submission and the overall codebase is four-pronged.  This includes expanding the factory suite to include many additional models.  Our second plan is to improve our test cases and our overall test plan to be more comprehensive of all branches present in our code to conduct more thorough testing using our new factories.  Our third change will be to modify the seeding files for the db in order to facilitate manual testing with RSwag.  Finally our fourth goal for the project is to improve our RSwag UI by implementing the previous three steps and then ensuring that manual testing capability is achieved and correct.&lt;br /&gt;
===Expanded Factory Suite===&lt;br /&gt;
For our final project we are seeking to improve the code base by expanding the factory suite to include factories for most of the 37 models present in the reimplementation backend repository. The rationale behind this decision is to improve the testing capabilities of all controllers either currently in the system or ones that will be added. As the code base grows, we expect an increased interdependency of the controllers on the model classes. Without factory classes, this would result in an opportunity for several DRY violations in the test suite. This hinders the maintainability of the code base and as small changes in the models could break the entire test suite and would need to be solved individually in every test case; however, with factories, we would only need to fix the code within the factories to reflect the new code structure and the test cases will remain largely unchanged. We would also suggest that factories be continuously updated as new models are added so that it aids in future maintainability.&lt;br /&gt;
&lt;br /&gt;
===Improved Test Plan===&lt;br /&gt;
* action_allowed&lt;br /&gt;
** If the user is a TA or higher, then a successful status will be returned for all actions.&lt;br /&gt;
** If the user is a student and requests to view their team then, then a successful status will be returned.&lt;br /&gt;
** Otherwise, a status of prohibited is rendered regardless of the action.&lt;br /&gt;
* view&lt;br /&gt;
** A successful status, the scores, the assignment, the averages, the meta average, and the review score count are all rendered so that the heat map can be displayed. &lt;br /&gt;
* view_team&lt;br /&gt;
** A successful status, the scores, the assignment with filtered questionnaire authors , the averages, the meta average, and the review score count are all rendered so that the heat map can be displayed. &lt;br /&gt;
* edit&lt;br /&gt;
** If the assignment participant is not found, then a not found status is rendered.&lt;br /&gt;
** Otherwise, a successful status, the participant, the questions, the scores, and the assignment are all rendered.&lt;br /&gt;
* instructor_review&lt;br /&gt;
** If the assignment participant is not found, then a not found status is rendered.&lt;br /&gt;
** If the instructor review is new then a response is rendered to tell the front end to go to the response controllers new action with the reviews mapping's id.&lt;br /&gt;
** Otherwise, a response is rendered to tell the front end to go to the response controller's edit action with the review's id.&lt;br /&gt;
* update&lt;br /&gt;
** If the team cannot be saved, then a bad request status is rendered.&lt;br /&gt;
** Otherwise, a response is rendered to tell the front end to go to the grades controller's view team action with the participant's id.&lt;br /&gt;
====Flow Chart====&lt;br /&gt;
[[File:Decision_tree.png|700px|An image showing flow chart]]&lt;br /&gt;
&lt;br /&gt;
===Modified db seeding===&lt;br /&gt;
Currently the file '''seeds.rb''' contains only an institution and admin user. To streamline testing and set up appropriate models, we will make sure the file contains the following:&lt;br /&gt;
* An assignment instance&lt;br /&gt;
* A participant instance&lt;br /&gt;
* A team instance&lt;br /&gt;
* An instructor instance&lt;br /&gt;
To perform testing for the API endpoints, these are the minimum model instances required. The goal of this change is to make sure we can handle manually testing the grades controller with the rswag UI. This is specifically for the reimplementation of the backend. There is an absence of several necessary POST API endpoints implementing CREATE operations. Without these seeded into the database, we would need to cover more implementation on endpoints.&lt;br /&gt;
&lt;br /&gt;
===Functional RSwagUI visualizations and manual testing capability===&lt;br /&gt;
Currently we have the endpoint visualizations set up on RSwag's UI, and just need to complete the previous steps for visualized results.&lt;br /&gt;
&lt;br /&gt;
=Team and Prior information=&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;br /&gt;
&lt;br /&gt;
==Previous Iterations==&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158757</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158757"/>
		<updated>2024-11-10T20:36:19Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: /* Functional RSwagUI visualizations and manual testing capability */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
===[https://drive.google.com/file/d/1lgFLevdhs7PTFpibxflQfB45nOXW04jA/view?usp=sharing Swagger Video Submission]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents. Additionally, we will be testing the controller with rswag.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor grade_controller.rb, which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
API::V1::GradesController utilizes action-based permissions through action_allowed to provide broader functionality to instructors versus students. With the frontend systems of the Grades Controller relying on heat map systems, view and view_team provide the detailed grading information to populate them (from the student perspective, reviewer identities are kept hidden). The edit method retrieves the relevant assignment to be modified by the frontend view. For accessing reviews, instructor_review is utilized, leading to access of previous reviews or instantiating new ones. Finally, grade changes are saved through the update function, which additionally covers comment feedback.&lt;br /&gt;
&lt;br /&gt;
This controller structure aligns closely with the traditional CRUD operations providing an organized way to handle grade management. The view and view_team actions are for the Read functionality, allowing both instructors and students to access and review grade data based on their roles. The Create aspect is handled in instructor_review, which either retrieves existing reviews or initiates new ones as needed, ensuring that instructors can easily add comments or feedback for an assignment.&lt;br /&gt;
&lt;br /&gt;
The Update action is fulfilled by update, which is responsible for saving new grading data and feedback from instructors. The Delete functionality is not something the grades_controller is responsible for handling.&lt;br /&gt;
&lt;br /&gt;
This CRUD focused approach makes sure that the refactored grade_controller.rb is efficient and easily maintainable, while offering both instructors and students a seamless experience in managing and reviewing assignment grades. The refactor further enhances clarity and accessibility, aiming to make each action intuitive and easily accessible to the relevant users within Expertiza.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's point of view, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's point of view which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's point of view&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
===Rationale for Changes===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
|-&lt;br /&gt;
|Added a new suite of API endpoint tests that are compatible with Rswag and tested our API endpoints thoroughly, additionally added factories for several projects in the system.&lt;br /&gt;
|As with any software change in a large system, testing is extremely important, so we wrote comprehensive tests for our endpoints.  Additionally, since the grades_controller is dependent on many other models (mainly because there is no grades model).  These changes will help future projects by providing factory methods for various models that did not currently have them in the system which should make testing for other groups easier in the future.&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Code Snippet===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Determines if the current user is able to perform :action as specified by the path parameter&lt;br /&gt;
  # If the user has the role of TA or higher they are granted access to all operations beyond view_team&lt;br /&gt;
  # Uses a switch statement for easy maintainability if added functionality is ever needed for students or&lt;br /&gt;
  # additional roles, to add more functionality simply add additional switch cases in the same syntax with&lt;br /&gt;
  # case 'action' and then some boolean check determining if that is allowed or forbidden.&lt;br /&gt;
  # GET /api/v1/grades/:action/action_allowed&lt;br /&gt;
  def action_allowed&lt;br /&gt;
    permitted = case params[:action]&lt;br /&gt;
                when 'view_team'&lt;br /&gt;
                  view_team_allowed?&lt;br /&gt;
                else&lt;br /&gt;
                  user_ta_privileges?&lt;br /&gt;
                end&lt;br /&gt;
    render json: { allowed: permitted }, status: permitted ? :ok : :forbidden&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides the needed functionality of querying needed values from the backend db and returning them to build the&lt;br /&gt;
  # heat map in the frontend from the TA/staff view.  These values are set in the get_data_for_heat_map method&lt;br /&gt;
  # which takes the assignment id as a parameter.&lt;br /&gt;
  # GET /api/v1/grades/:id/view&lt;br /&gt;
  def view&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    render json: { scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                   review_score_count: @review_score_count }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides all relevant data for the student perspective for the heat map page as well as the&lt;br /&gt;
  # needed information to showcase the questionnaires from the student view.  Additionally, handles the removal of user&lt;br /&gt;
  # identification in the reviews within the hide_reviewers_rom_student method.&lt;br /&gt;
  # GET /api/v1/grades/:id/view_team&lt;br /&gt;
  def view_team&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    @scores[:participants] = hide_reviewers_from_student&lt;br /&gt;
    questionnaires = @assignment.questionnaires&lt;br /&gt;
    questions = retrieve_questions(questionnaires, @assignment.id)&lt;br /&gt;
    render json: {scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                  review_score_count: @review_score_count, questions: questions }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Sets information required for editing the grade information, this includes the participant, questions, scores, and&lt;br /&gt;
  # assignment&lt;br /&gt;
  # GET /api/v1/grades/:id/edit&lt;br /&gt;
  def edit&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: {message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot;}, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    questions = list_questions(assignment)&lt;br /&gt;
    scores = review_grades(assignment, questions)&lt;br /&gt;
    render json: {participant: participant, questions: questions, scores: scores, assignment: assignment}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides functionality that handles informing the frontend which controller and action to direct to for instructor&lt;br /&gt;
  # review given the current state of the system.  The intended controller to handle the creation or editing of a review&lt;br /&gt;
  # is the response controller, however this method just determines if a new review must be made based on figuring out&lt;br /&gt;
  # whether or not an associated review_mapping exists from the participant already.  If one does they should go to&lt;br /&gt;
  # Response#edit and if one does not they should go to Response#new.  Only ever returns a status of ok.&lt;br /&gt;
  # GET /api/v1/grades/:id/instructor_review&lt;br /&gt;
  def instructor_review&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: { message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot; }, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    review_mapping = find_participant_review_mapping(participant)&lt;br /&gt;
    if review_mapping.new_record?&lt;br /&gt;
      render json: { controller: 'response', action: 'new', id: review_mapping.map_id,&lt;br /&gt;
                     return: 'instructor'}, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      review = Response.find_by(map_id: review_mapping.map_id)&lt;br /&gt;
      render json: { controller: 'response', action: 'edit', id: review.id, return: 'instructor'}, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Update method for the grade associated with a team, allows an instructor to upgrade a team's grade with a grade&lt;br /&gt;
  # and a comment on their assignment for submission.  The team is then saved with this change in order to be accessed&lt;br /&gt;
  # elsewhere in the code for needed scoring evaluations.  If a failure occurs while saving the team then this will&lt;br /&gt;
  # return a bad_request response complete with a message and the global ERROR_INFO which can be set elsewhere for&lt;br /&gt;
  # further error handling mechanisms&lt;br /&gt;
  # PATCH /api/v1/grades/:participant_id/update/:grade_for_submission&lt;br /&gt;
  def update&lt;br /&gt;
    participant = AssignmentParticipant.find_by(id: params[:participant_id])&lt;br /&gt;
&lt;br /&gt;
    team = participant.team&lt;br /&gt;
    team.grade_for_submission = params[:grade_for_submission]&lt;br /&gt;
    team.comment_for_submission = params[:comment_for_submission]&lt;br /&gt;
    begin&lt;br /&gt;
      team.save&lt;br /&gt;
    rescue StandardError =&amp;gt; e&lt;br /&gt;
      render json: {message: &amp;quot;Error occurred while updating grade for team #{team.id}&amp;quot;,&lt;br /&gt;
                    error: e.message }, status: :bad_request&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: { controller: 'grades', action: 'view_team', id: participant.id}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===CRUD functionality===&lt;br /&gt;
Before we did our refactor and reimplementation the grades_controller contained several unnecessary methods as well as functions vastly beyond the CRUD operations that belong within a controller like this.  The two CRUD operations that are presently in the system for the grades_controller are read and updated.  The read operation is implemented within the view and view_team method to provide the needed information to view the grade heat map.  Then the update functionality is primarily implemented in the needed edit method which supplies information before the update and the update method has been vastly modified from its old implementation where it was not actually saving objects, we have replaced that with a proper update that modifies the grade and comment similarly to how the old save_grade_and_comment_for_submission method used to work.&lt;br /&gt;
===SOLID Principles===&lt;br /&gt;
Overall we strove to meet SOLID guidelines by limiting the scope of the controller back down to its intended core functionality.  This helped satisfy the single responsibility principle by removing additional functionality beyond the intended scope of this class.  We have also significantly cut down on the required helpers needed for these operations through our implementation of a new model participant_scores which helps serve the singular goal of keeping track of score information for questions on an assignment for a given participant. We have also improved the maintainability of the code by making our methods more atomic which should promote extension outside of our methods for new functionality satisfying the Open/Close principle. The remaining three principles did not really apply to this project as the grades_controller has minimal interactions with it's superclass and has no independent model that it controls or is responsible for governing.&lt;br /&gt;
===DRY principle===&lt;br /&gt;
To satisfy the don't repeat yourself principle we sought to make private helper methods to abstract repeated code that was adding complexity to our methods.  One such method is the get_data_for_heat_map method which replaces a substantial amount of what used to be complex and repeated code, which has now been significantly simplified for readability.  Please see the snippet below for the new method, it's primary goal is to set the instance variables of the controller as needed so we can prepare data for the heat map as needed in the front end.  We also relocated complex code that did not aid in the readability into helper methods which have also been refactored, the main goal of this was to promote readability in the main endpoint methods remove unnecessary clutter from the code, and limit code repetition in future modifications by providing modular helper methods for functionality that we believe may need to be repeated in future enhancements such as listing the questions or querying review grades.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Provides data for the heat maps in the view statements&lt;br /&gt;
  def get_data_for_heat_map(id)&lt;br /&gt;
    # Finds the assignment&lt;br /&gt;
    @assignment = Assignment.find(id)&lt;br /&gt;
    # Extracts the questionnaires&lt;br /&gt;
    @questions = filter_questionnaires(@assignment)&lt;br /&gt;
    @scores = review_grades(@assignment, @questions)&lt;br /&gt;
    @review_score_count = @scores[:teams].length # After rejecting nil scores need original length to iterate over hash&lt;br /&gt;
    @averages = vector(@scores)&lt;br /&gt;
    @avg_of_avg = mean(@averages)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Testing Details===&lt;br /&gt;
The test file can be located at:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spec/requests/api/v1/grades_controller_spec.rb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''action_allowed'''&lt;br /&gt;
** Passes in the view action and an assignment we wish to view. Determines if the user has the appropriate permissions to view it.&lt;br /&gt;
*'''view'''&lt;br /&gt;
** Passes in the id of the assignment and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''view_team'''&lt;br /&gt;
** Pasess in the assignment id and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''edit'''&lt;br /&gt;
** Passes in the id of the assignment and expects the participant's id, the same assignment's id, '''questions''', and '''scores'''.&lt;br /&gt;
*'''instructor_review'''&lt;br /&gt;
** Passes in the id of a participant and expects '''controller''', '''action''', the same participant id, and the instructor.&lt;br /&gt;
*'''update'''&lt;br /&gt;
** Passes in a participant id and a body which contains '''grade_for_submission''' (integer) and '''comment_for_submission''' (string). Expects the same grade, comment, '''action''', and participant's id.&lt;br /&gt;
&lt;br /&gt;
'''Rswag UI'''&lt;br /&gt;
[[File:Grades_controller_test_fall_2024.png|700px|An image showing the rswag ui of accepted test results.]]&lt;br /&gt;
=Final project additions=&lt;br /&gt;
==The Problem and Remaining Work==&lt;br /&gt;
While working on our OSS project we ran into substantial difficulties with testing our controller.  The primary reason for this is that the grades_controller is one of the first controller classes in the reimplementation backend that does not have a primary model associated with it.  This is because it does not seem prudent to make a grades model, as scores can be held and tracked as fields in other objects as primitives so this abstraction would not be particularly helpful.  However, this poses an interesting challenge when testing and reimplementing the controller.  Specifically, the dependency on the successful initialization of numerous models throughout the controller including Assignment, Participant, and Team to name a few of the model classes required for operations within the grades_controller for the present create and edit CRUD operations implemented within.  During our OSS project, we were able to slim down the controller and implement more elegant and atomic solutions to the tasks that the original controller was responsible for with some refactoring and reimplementation of various methods.  However, even with these changes, the grades_controller is still dependent on several other classes and their interactions within the system being initialized and in a valid state in order to perform (or test) the required operations.&lt;br /&gt;
&lt;br /&gt;
The primary difficulty in testing our controller as indicated above was this high dependency on other models for correct functionality.  Because of this, we had to construct and instantiate several different models in our test code.  This, in a vacuum, may not be an issue.  However, as the reimplementation backend codebase continues to grow this issue has the potential to become a recurring one where the ultimate result will be several violations of the DRY principle in the testing suite instantiating needed objects inside of controller tests similarly to the way that we had to do this at the start.  In the current codebase, the only models containing factory code are student_task, join_team_request, bookmark, and user, making this substantially shy of the thirty-six models currently residing within the reimplementation_backend repository.  We will seek to change this in order to limit the likelihood of DRY violations in the test suite moving forward to improve code maintainability and consistency.  &lt;br /&gt;
==Our solution==&lt;br /&gt;
Our solution to improving our OSS submission and the overall codebase is four-pronged.  This includes expanding the factory suite to include many additional models.  Our second plan is to improve our test cases and our overall test plan to be more comprehensive of all branches present in our code to conduct more thorough testing using our new factories.  Our third change will be to modify the seeding files for the db in order to facilitate manual testing with RSwag.  Finally our fourth goal for the project is to improve our RSwag UI by implementing the previous three steps and then ensuring that manual testing capability is achieved and correct.&lt;br /&gt;
===Expanded Factory Suite===&lt;br /&gt;
For our final project we are seeking to improve the code base by expanding the factory suite to include factories for most of the 37 models present in the reimplementation backend repository. The rationale behind this decision is to improve the testing capabilities of all controllers either currently in the system or ones that will be added. As the code base grows, we expect an increased interdependency of the controllers on the model classes. Without factory classes, this would result in an opportunity for several DRY violations in the test suite. This hinders the maintainability of the code base and as small changes in the models could break the entire test suite and would need to be solved individually in every test case; however, with factories, we would only need to fix the code within the factories to reflect the new code structure and the test cases will remain largely unchanged. We would also suggest that factories be continuously updated as new models are added so that it aids in future maintainability.&lt;br /&gt;
&lt;br /&gt;
===Improved Test Plan===&lt;br /&gt;
* action_allowed&lt;br /&gt;
** If the user is a TA or higher, then a successful status will be returned for all actions.&lt;br /&gt;
** If the user is a student and requests to view their team then, then a successful status will be returned.&lt;br /&gt;
** Otherwise, a status of prohibited is rendered regardless of the action.&lt;br /&gt;
* view&lt;br /&gt;
** A successful status, the scores, the assignment, the averages, the meta average, and the review score count are all rendered so that the heat map can be displayed. &lt;br /&gt;
* view_team&lt;br /&gt;
** A successful status, the scores, the assignment with filtered questionnaire authors , the averages, the meta average, and the review score count are all rendered so that the heat map can be displayed. &lt;br /&gt;
* edit&lt;br /&gt;
** If the assignment participant is not found, then a not found status is rendered.&lt;br /&gt;
** Otherwise, a successful status, the participant, the questions, the scores, and the assignment are all rendered.&lt;br /&gt;
* instructor_review&lt;br /&gt;
** If the assignment participant is not found, then a not found status is rendered.&lt;br /&gt;
** If the instructor review is new then a response is rendered to tell the front end to go to the response controllers new action with the reviews mapping's id.&lt;br /&gt;
** Otherwise, a response is rendered to tell the front end to go to the response controller's edit action with the review's id.&lt;br /&gt;
* update&lt;br /&gt;
** If the team cannot be saved, then a bad request status is rendered.&lt;br /&gt;
** Otherwise, a response is rendered to tell the front end to go to the grades controller's view team action with the participant's id.&lt;br /&gt;
====Flow Chart====&lt;br /&gt;
[[File:Decision_tree.png|700px|An image showing flow chart]]&lt;br /&gt;
&lt;br /&gt;
===Modified db seeding===&lt;br /&gt;
Currently the file *seeds.rb* contains only an institution and admin user. To streamline testing and set up appropriate models, we will make sure the file contains the following:&lt;br /&gt;
* An assignment instance&lt;br /&gt;
* A participant instance&lt;br /&gt;
* A team instance&lt;br /&gt;
* An instructor instance&lt;br /&gt;
To perform testing for the API endpoints, these are the minimum model instances required. The goal of this change is to make sure we can handle manually testing the grades controller with the rswag UI. This is specifically for the reimplementation of the backend. There is an absence of several necessary POST API endpoints implementing CREATE operations. Without these seeded into the database, we would need to cover more implementation on endpoints.&lt;br /&gt;
&lt;br /&gt;
===Functional RSwagUI visualizations and manual testing capability===&lt;br /&gt;
Currently we have the endpoint visualizations set up on RSwag's UI, and just need to complete the previous steps for visualized results.&lt;br /&gt;
&lt;br /&gt;
=Team and Prior information=&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;br /&gt;
&lt;br /&gt;
==Previous Iterations==&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158756</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158756"/>
		<updated>2024-11-10T20:34:34Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: /* Modified db seeding */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
===[https://drive.google.com/file/d/1lgFLevdhs7PTFpibxflQfB45nOXW04jA/view?usp=sharing Swagger Video Submission]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents. Additionally, we will be testing the controller with rswag.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor grade_controller.rb, which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
API::V1::GradesController utilizes action-based permissions through action_allowed to provide broader functionality to instructors versus students. With the frontend systems of the Grades Controller relying on heat map systems, view and view_team provide the detailed grading information to populate them (from the student perspective, reviewer identities are kept hidden). The edit method retrieves the relevant assignment to be modified by the frontend view. For accessing reviews, instructor_review is utilized, leading to access of previous reviews or instantiating new ones. Finally, grade changes are saved through the update function, which additionally covers comment feedback.&lt;br /&gt;
&lt;br /&gt;
This controller structure aligns closely with the traditional CRUD operations providing an organized way to handle grade management. The view and view_team actions are for the Read functionality, allowing both instructors and students to access and review grade data based on their roles. The Create aspect is handled in instructor_review, which either retrieves existing reviews or initiates new ones as needed, ensuring that instructors can easily add comments or feedback for an assignment.&lt;br /&gt;
&lt;br /&gt;
The Update action is fulfilled by update, which is responsible for saving new grading data and feedback from instructors. The Delete functionality is not something the grades_controller is responsible for handling.&lt;br /&gt;
&lt;br /&gt;
This CRUD focused approach makes sure that the refactored grade_controller.rb is efficient and easily maintainable, while offering both instructors and students a seamless experience in managing and reviewing assignment grades. The refactor further enhances clarity and accessibility, aiming to make each action intuitive and easily accessible to the relevant users within Expertiza.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's point of view, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's point of view which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's point of view&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
===Rationale for Changes===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
|-&lt;br /&gt;
|Added a new suite of API endpoint tests that are compatible with Rswag and tested our API endpoints thoroughly, additionally added factories for several projects in the system.&lt;br /&gt;
|As with any software change in a large system, testing is extremely important, so we wrote comprehensive tests for our endpoints.  Additionally, since the grades_controller is dependent on many other models (mainly because there is no grades model).  These changes will help future projects by providing factory methods for various models that did not currently have them in the system which should make testing for other groups easier in the future.&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Code Snippet===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Determines if the current user is able to perform :action as specified by the path parameter&lt;br /&gt;
  # If the user has the role of TA or higher they are granted access to all operations beyond view_team&lt;br /&gt;
  # Uses a switch statement for easy maintainability if added functionality is ever needed for students or&lt;br /&gt;
  # additional roles, to add more functionality simply add additional switch cases in the same syntax with&lt;br /&gt;
  # case 'action' and then some boolean check determining if that is allowed or forbidden.&lt;br /&gt;
  # GET /api/v1/grades/:action/action_allowed&lt;br /&gt;
  def action_allowed&lt;br /&gt;
    permitted = case params[:action]&lt;br /&gt;
                when 'view_team'&lt;br /&gt;
                  view_team_allowed?&lt;br /&gt;
                else&lt;br /&gt;
                  user_ta_privileges?&lt;br /&gt;
                end&lt;br /&gt;
    render json: { allowed: permitted }, status: permitted ? :ok : :forbidden&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides the needed functionality of querying needed values from the backend db and returning them to build the&lt;br /&gt;
  # heat map in the frontend from the TA/staff view.  These values are set in the get_data_for_heat_map method&lt;br /&gt;
  # which takes the assignment id as a parameter.&lt;br /&gt;
  # GET /api/v1/grades/:id/view&lt;br /&gt;
  def view&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    render json: { scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                   review_score_count: @review_score_count }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides all relevant data for the student perspective for the heat map page as well as the&lt;br /&gt;
  # needed information to showcase the questionnaires from the student view.  Additionally, handles the removal of user&lt;br /&gt;
  # identification in the reviews within the hide_reviewers_rom_student method.&lt;br /&gt;
  # GET /api/v1/grades/:id/view_team&lt;br /&gt;
  def view_team&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    @scores[:participants] = hide_reviewers_from_student&lt;br /&gt;
    questionnaires = @assignment.questionnaires&lt;br /&gt;
    questions = retrieve_questions(questionnaires, @assignment.id)&lt;br /&gt;
    render json: {scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                  review_score_count: @review_score_count, questions: questions }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Sets information required for editing the grade information, this includes the participant, questions, scores, and&lt;br /&gt;
  # assignment&lt;br /&gt;
  # GET /api/v1/grades/:id/edit&lt;br /&gt;
  def edit&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: {message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot;}, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    questions = list_questions(assignment)&lt;br /&gt;
    scores = review_grades(assignment, questions)&lt;br /&gt;
    render json: {participant: participant, questions: questions, scores: scores, assignment: assignment}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides functionality that handles informing the frontend which controller and action to direct to for instructor&lt;br /&gt;
  # review given the current state of the system.  The intended controller to handle the creation or editing of a review&lt;br /&gt;
  # is the response controller, however this method just determines if a new review must be made based on figuring out&lt;br /&gt;
  # whether or not an associated review_mapping exists from the participant already.  If one does they should go to&lt;br /&gt;
  # Response#edit and if one does not they should go to Response#new.  Only ever returns a status of ok.&lt;br /&gt;
  # GET /api/v1/grades/:id/instructor_review&lt;br /&gt;
  def instructor_review&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: { message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot; }, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    review_mapping = find_participant_review_mapping(participant)&lt;br /&gt;
    if review_mapping.new_record?&lt;br /&gt;
      render json: { controller: 'response', action: 'new', id: review_mapping.map_id,&lt;br /&gt;
                     return: 'instructor'}, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      review = Response.find_by(map_id: review_mapping.map_id)&lt;br /&gt;
      render json: { controller: 'response', action: 'edit', id: review.id, return: 'instructor'}, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Update method for the grade associated with a team, allows an instructor to upgrade a team's grade with a grade&lt;br /&gt;
  # and a comment on their assignment for submission.  The team is then saved with this change in order to be accessed&lt;br /&gt;
  # elsewhere in the code for needed scoring evaluations.  If a failure occurs while saving the team then this will&lt;br /&gt;
  # return a bad_request response complete with a message and the global ERROR_INFO which can be set elsewhere for&lt;br /&gt;
  # further error handling mechanisms&lt;br /&gt;
  # PATCH /api/v1/grades/:participant_id/update/:grade_for_submission&lt;br /&gt;
  def update&lt;br /&gt;
    participant = AssignmentParticipant.find_by(id: params[:participant_id])&lt;br /&gt;
&lt;br /&gt;
    team = participant.team&lt;br /&gt;
    team.grade_for_submission = params[:grade_for_submission]&lt;br /&gt;
    team.comment_for_submission = params[:comment_for_submission]&lt;br /&gt;
    begin&lt;br /&gt;
      team.save&lt;br /&gt;
    rescue StandardError =&amp;gt; e&lt;br /&gt;
      render json: {message: &amp;quot;Error occurred while updating grade for team #{team.id}&amp;quot;,&lt;br /&gt;
                    error: e.message }, status: :bad_request&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: { controller: 'grades', action: 'view_team', id: participant.id}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===CRUD functionality===&lt;br /&gt;
Before we did our refactor and reimplementation the grades_controller contained several unnecessary methods as well as functions vastly beyond the CRUD operations that belong within a controller like this.  The two CRUD operations that are presently in the system for the grades_controller are read and updated.  The read operation is implemented within the view and view_team method to provide the needed information to view the grade heat map.  Then the update functionality is primarily implemented in the needed edit method which supplies information before the update and the update method has been vastly modified from its old implementation where it was not actually saving objects, we have replaced that with a proper update that modifies the grade and comment similarly to how the old save_grade_and_comment_for_submission method used to work.&lt;br /&gt;
===SOLID Principles===&lt;br /&gt;
Overall we strove to meet SOLID guidelines by limiting the scope of the controller back down to its intended core functionality.  This helped satisfy the single responsibility principle by removing additional functionality beyond the intended scope of this class.  We have also significantly cut down on the required helpers needed for these operations through our implementation of a new model participant_scores which helps serve the singular goal of keeping track of score information for questions on an assignment for a given participant. We have also improved the maintainability of the code by making our methods more atomic which should promote extension outside of our methods for new functionality satisfying the Open/Close principle. The remaining three principles did not really apply to this project as the grades_controller has minimal interactions with it's superclass and has no independent model that it controls or is responsible for governing.&lt;br /&gt;
===DRY principle===&lt;br /&gt;
To satisfy the don't repeat yourself principle we sought to make private helper methods to abstract repeated code that was adding complexity to our methods.  One such method is the get_data_for_heat_map method which replaces a substantial amount of what used to be complex and repeated code, which has now been significantly simplified for readability.  Please see the snippet below for the new method, it's primary goal is to set the instance variables of the controller as needed so we can prepare data for the heat map as needed in the front end.  We also relocated complex code that did not aid in the readability into helper methods which have also been refactored, the main goal of this was to promote readability in the main endpoint methods remove unnecessary clutter from the code, and limit code repetition in future modifications by providing modular helper methods for functionality that we believe may need to be repeated in future enhancements such as listing the questions or querying review grades.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Provides data for the heat maps in the view statements&lt;br /&gt;
  def get_data_for_heat_map(id)&lt;br /&gt;
    # Finds the assignment&lt;br /&gt;
    @assignment = Assignment.find(id)&lt;br /&gt;
    # Extracts the questionnaires&lt;br /&gt;
    @questions = filter_questionnaires(@assignment)&lt;br /&gt;
    @scores = review_grades(@assignment, @questions)&lt;br /&gt;
    @review_score_count = @scores[:teams].length # After rejecting nil scores need original length to iterate over hash&lt;br /&gt;
    @averages = vector(@scores)&lt;br /&gt;
    @avg_of_avg = mean(@averages)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Testing Details===&lt;br /&gt;
The test file can be located at:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spec/requests/api/v1/grades_controller_spec.rb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''action_allowed'''&lt;br /&gt;
** Passes in the view action and an assignment we wish to view. Determines if the user has the appropriate permissions to view it.&lt;br /&gt;
*'''view'''&lt;br /&gt;
** Passes in the id of the assignment and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''view_team'''&lt;br /&gt;
** Pasess in the assignment id and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''edit'''&lt;br /&gt;
** Passes in the id of the assignment and expects the participant's id, the same assignment's id, '''questions''', and '''scores'''.&lt;br /&gt;
*'''instructor_review'''&lt;br /&gt;
** Passes in the id of a participant and expects '''controller''', '''action''', the same participant id, and the instructor.&lt;br /&gt;
*'''update'''&lt;br /&gt;
** Passes in a participant id and a body which contains '''grade_for_submission''' (integer) and '''comment_for_submission''' (string). Expects the same grade, comment, '''action''', and participant's id.&lt;br /&gt;
&lt;br /&gt;
'''Rswag UI'''&lt;br /&gt;
[[File:Grades_controller_test_fall_2024.png|700px|An image showing the rswag ui of accepted test results.]]&lt;br /&gt;
=Final project additions=&lt;br /&gt;
==The Problem and Remaining Work==&lt;br /&gt;
While working on our OSS project we ran into substantial difficulties with testing our controller.  The primary reason for this is that the grades_controller is one of the first controller classes in the reimplementation backend that does not have a primary model associated with it.  This is because it does not seem prudent to make a grades model, as scores can be held and tracked as fields in other objects as primitives so this abstraction would not be particularly helpful.  However, this poses an interesting challenge when testing and reimplementing the controller.  Specifically, the dependency on the successful initialization of numerous models throughout the controller including Assignment, Participant, and Team to name a few of the model classes required for operations within the grades_controller for the present create and edit CRUD operations implemented within.  During our OSS project, we were able to slim down the controller and implement more elegant and atomic solutions to the tasks that the original controller was responsible for with some refactoring and reimplementation of various methods.  However, even with these changes, the grades_controller is still dependent on several other classes and their interactions within the system being initialized and in a valid state in order to perform (or test) the required operations.&lt;br /&gt;
&lt;br /&gt;
The primary difficulty in testing our controller as indicated above was this high dependency on other models for correct functionality.  Because of this, we had to construct and instantiate several different models in our test code.  This, in a vacuum, may not be an issue.  However, as the reimplementation backend codebase continues to grow this issue has the potential to become a recurring one where the ultimate result will be several violations of the DRY principle in the testing suite instantiating needed objects inside of controller tests similarly to the way that we had to do this at the start.  In the current codebase, the only models containing factory code are student_task, join_team_request, bookmark, and user, making this substantially shy of the thirty-six models currently residing within the reimplementation_backend repository.  We will seek to change this in order to limit the likelihood of DRY violations in the test suite moving forward to improve code maintainability and consistency.  &lt;br /&gt;
==Our solution==&lt;br /&gt;
Our solution to improving our OSS submission and the overall codebase is four-pronged.  This includes expanding the factory suite to include many additional models.  Our second plan is to improve our test cases and our overall test plan to be more comprehensive of all branches present in our code to conduct more thorough testing using our new factories.  Our third change will be to modify the seeding files for the db in order to facilitate manual testing with RSwag.  Finally our fourth goal for the project is to improve our RSwag UI by implementing the previous three steps and then ensuring that manual testing capability is achieved and correct.&lt;br /&gt;
===Expanded Factory Suite===&lt;br /&gt;
For our final project we are seeking to improve the code base by expanding the factory suite to include factories for most of the 37 models present in the reimplementation backend repository. The rationale behind this decision is to improve the testing capabilities of all controllers either currently in the system or ones that will be added. As the code base grows, we expect an increased interdependency of the controllers on the model classes. Without factory classes, this would result in an opportunity for several DRY violations in the test suite. This hinders the maintainability of the code base and as small changes in the models could break the entire test suite and would need to be solved individually in every test case; however, with factories, we would only need to fix the code within the factories to reflect the new code structure and the test cases will remain largely unchanged. We would also suggest that factories be continuously updated as new models are added so that it aids in future maintainability.&lt;br /&gt;
&lt;br /&gt;
===Improved Test Plan===&lt;br /&gt;
* action_allowed&lt;br /&gt;
** If the user is a TA or higher, then a successful status will be returned for all actions.&lt;br /&gt;
** If the user is a student and requests to view their team then, then a successful status will be returned.&lt;br /&gt;
** Otherwise, a status of prohibited is rendered regardless of the action.&lt;br /&gt;
* view&lt;br /&gt;
** A successful status, the scores, the assignment, the averages, the meta average, and the review score count are all rendered so that the heat map can be displayed. &lt;br /&gt;
* view_team&lt;br /&gt;
** A successful status, the scores, the assignment with filtered questionnaire authors , the averages, the meta average, and the review score count are all rendered so that the heat map can be displayed. &lt;br /&gt;
* edit&lt;br /&gt;
** If the assignment participant is not found, then a not found status is rendered.&lt;br /&gt;
** Otherwise, a successful status, the participant, the questions, the scores, and the assignment are all rendered.&lt;br /&gt;
* instructor_review&lt;br /&gt;
** If the assignment participant is not found, then a not found status is rendered.&lt;br /&gt;
** If the instructor review is new then a response is rendered to tell the front end to go to the response controllers new action with the reviews mapping's id.&lt;br /&gt;
** Otherwise, a response is rendered to tell the front end to go to the response controller's edit action with the review's id.&lt;br /&gt;
* update&lt;br /&gt;
** If the team cannot be saved, then a bad request status is rendered.&lt;br /&gt;
** Otherwise, a response is rendered to tell the front end to go to the grades controller's view team action with the participant's id.&lt;br /&gt;
====Flow Chart====&lt;br /&gt;
[[File:Decision_tree.png|700px|An image showing flow chart]]&lt;br /&gt;
&lt;br /&gt;
===Modified db seeding===&lt;br /&gt;
Currently the file *seeds.rb* contains only an institution and admin user. To streamline testing and set up appropriate models, we will make sure the file contains the following:&lt;br /&gt;
* An assignment instance&lt;br /&gt;
* A participant instance&lt;br /&gt;
* A team instance&lt;br /&gt;
* An instructor instance&lt;br /&gt;
To perform testing for the API endpoints, these are the minimum model instances required. The goal of this change is to make sure we can handle manually testing the grades controller with the rswag UI. This is specifically for the reimplementation of the backend. There is an absence of several necessary POST API endpoints implementing CREATE operations. Without these seeded into the database, we would need to cover more implementation on endpoints.&lt;br /&gt;
&lt;br /&gt;
===Functional RSwagUI visualizations and manual testing capability===&lt;br /&gt;
=Team and Prior information=&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;br /&gt;
&lt;br /&gt;
==Previous Iterations==&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158374</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158374"/>
		<updated>2024-10-30T03:00:46Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: /* Our Goals */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
===[https://drive.google.com/file/d/1lgFLevdhs7PTFpibxflQfB45nOXW04jA/view?usp=sharing Swagger Video Submission]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents. Additionally, we will be testing the controller with rswag.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor grade_controller.rb, which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
API::V1::GradesController utilizes action-based permissions through action_allowed to provide broader functionality to instructors versus students. With the frontend systems of the Grades Controller relying on heat map systems, view and view_team provide the detailed grading information to populate them (from the student perspective, reviewer identities are kept hidden). The edit method retrieves the relevant assignment to be modified by the frontend view. For accessing reviews, instructor_review is utilized, leading to access of previous reviews or instantiating new ones. Finally, grade changes are saved through the update function, which additionally covers comment feedback.&lt;br /&gt;
&lt;br /&gt;
This controller structure aligns closely with the traditional CRUD operations providing an organized way to handle grade management. The view and view_team actions are for the Read functionality, allowing both instructors and students to access and review grade data based on their roles. The Create aspect is handled in instructor_review, which either retrieves existing reviews or initiates new ones as needed, ensuring that instructors can easily add comments or feedback for an assignment.&lt;br /&gt;
&lt;br /&gt;
The Update action is fulfilled by update, which is responsible for saving new grading data and feedback from instructors. The Delete functionality is not something the grades_controller is responsible for handling.&lt;br /&gt;
&lt;br /&gt;
This CRUD focused approach makes sure that the refactored grade_controller.rb is efficient and easily maintainable, while offering both instructors and students a seamless experience in managing and reviewing assignment grades. The refactor further enhances clarity and accessibility, aiming to make each action intuitive and easily accessible to the relevant users within Expertiza.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's point of view, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's point of view which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's point of view&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
===Rationale for Changes===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
|-&lt;br /&gt;
|Added a new suite of API endpoint tests that are compatible with Rswag and tested our API endpoints thoroughly, additionally added factories for several projects in the system.&lt;br /&gt;
|As with any software change in a large system, testing is extremely important, so we wrote comprehensive tests for our endpoints.  Additionally, since the grades_controller is dependent on many other models (mainly because there is no grades model).  These changes will help future projects by providing factory methods for various models that did not currently have them in the system which should make testing for other groups easier in the future.&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Code Snippet===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Determines if the current user is able to perform :action as specified by the path parameter&lt;br /&gt;
  # If the user has the role of TA or higher they are granted access to all operations beyond view_team&lt;br /&gt;
  # Uses a switch statement for easy maintainability if added functionality is ever needed for students or&lt;br /&gt;
  # additional roles, to add more functionality simply add additional switch cases in the same syntax with&lt;br /&gt;
  # case 'action' and then some boolean check determining if that is allowed or forbidden.&lt;br /&gt;
  # GET /api/v1/grades/:action/action_allowed&lt;br /&gt;
  def action_allowed&lt;br /&gt;
    permitted = case params[:action]&lt;br /&gt;
                when 'view_team'&lt;br /&gt;
                  view_team_allowed?&lt;br /&gt;
                else&lt;br /&gt;
                  user_ta_privileges?&lt;br /&gt;
                end&lt;br /&gt;
    render json: { allowed: permitted }, status: permitted ? :ok : :forbidden&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides the needed functionality of querying needed values from the backend db and returning them to build the&lt;br /&gt;
  # heat map in the frontend from the TA/staff view.  These values are set in the get_data_for_heat_map method&lt;br /&gt;
  # which takes the assignment id as a parameter.&lt;br /&gt;
  # GET /api/v1/grades/:id/view&lt;br /&gt;
  def view&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    render json: { scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                   review_score_count: @review_score_count }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides all relevant data for the student perspective for the heat map page as well as the&lt;br /&gt;
  # needed information to showcase the questionnaires from the student view.  Additionally, handles the removal of user&lt;br /&gt;
  # identification in the reviews within the hide_reviewers_rom_student method.&lt;br /&gt;
  # GET /api/v1/grades/:id/view_team&lt;br /&gt;
  def view_team&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    @scores[:participants] = hide_reviewers_from_student&lt;br /&gt;
    questionnaires = @assignment.questionnaires&lt;br /&gt;
    questions = retrieve_questions(questionnaires, @assignment.id)&lt;br /&gt;
    render json: {scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                  review_score_count: @review_score_count, questions: questions }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Sets information required for editing the grade information, this includes the participant, questions, scores, and&lt;br /&gt;
  # assignment&lt;br /&gt;
  # GET /api/v1/grades/:id/edit&lt;br /&gt;
  def edit&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: {message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot;}, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    questions = list_questions(assignment)&lt;br /&gt;
    scores = review_grades(assignment, questions)&lt;br /&gt;
    render json: {participant: participant, questions: questions, scores: scores, assignment: assignment}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides functionality that handles informing the frontend which controller and action to direct to for instructor&lt;br /&gt;
  # review given the current state of the system.  The intended controller to handle the creation or editing of a review&lt;br /&gt;
  # is the response controller, however this method just determines if a new review must be made based on figuring out&lt;br /&gt;
  # whether or not an associated review_mapping exists from the participant already.  If one does they should go to&lt;br /&gt;
  # Response#edit and if one does not they should go to Response#new.  Only ever returns a status of ok.&lt;br /&gt;
  # GET /api/v1/grades/:id/instructor_review&lt;br /&gt;
  def instructor_review&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: { message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot; }, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    review_mapping = find_participant_review_mapping(participant)&lt;br /&gt;
    if review_mapping.new_record?&lt;br /&gt;
      render json: { controller: 'response', action: 'new', id: review_mapping.map_id,&lt;br /&gt;
                     return: 'instructor'}, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      review = Response.find_by(map_id: review_mapping.map_id)&lt;br /&gt;
      render json: { controller: 'response', action: 'edit', id: review.id, return: 'instructor'}, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Update method for the grade associated with a team, allows an instructor to upgrade a team's grade with a grade&lt;br /&gt;
  # and a comment on their assignment for submission.  The team is then saved with this change in order to be accessed&lt;br /&gt;
  # elsewhere in the code for needed scoring evaluations.  If a failure occurs while saving the team then this will&lt;br /&gt;
  # return a bad_request response complete with a message and the global ERROR_INFO which can be set elsewhere for&lt;br /&gt;
  # further error handling mechanisms&lt;br /&gt;
  # PATCH /api/v1/grades/:participant_id/update/:grade_for_submission&lt;br /&gt;
  def update&lt;br /&gt;
    participant = AssignmentParticipant.find_by(id: params[:participant_id])&lt;br /&gt;
&lt;br /&gt;
    team = participant.team&lt;br /&gt;
    team.grade_for_submission = params[:grade_for_submission]&lt;br /&gt;
    team.comment_for_submission = params[:comment_for_submission]&lt;br /&gt;
    begin&lt;br /&gt;
      team.save&lt;br /&gt;
    rescue StandardError =&amp;gt; e&lt;br /&gt;
      render json: {message: &amp;quot;Error occurred while updating grade for team #{team.id}&amp;quot;,&lt;br /&gt;
                    error: e.message }, status: :bad_request&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: { controller: 'grades', action: 'view_team', id: participant.id}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===CRUD functionality===&lt;br /&gt;
Before we did our refactor and reimplementation the grades_controller contained several unnecessary methods as well as functions vastly beyond the CRUD operations that belong within a controller like this.  The two CRUD operations that are presently in the system for the grades_controller are read and updated.  The read operation is implemented within the view and view_team method to provide the needed information to view the grade heat map.  Then the update functionality is primarily implemented in the needed edit method which supplies information before the update and the update method has been vastly modified from its old implementation where it was not actually saving objects, we have replaced that with a proper update that modifies the grade and comment similarly to how the old save_grade_and_comment_for_submission method used to work.&lt;br /&gt;
===SOLID Principles===&lt;br /&gt;
Overall we strove to meet SOLID guidelines by limiting the scope of the controller back down to its intended core functionality.  This helped satisfy the single responsibility principle by removing additional functionality beyond the intended scope of this class.  We have also significantly cut down on the required helpers needed for these operations through our implementation of a new model participant_scores which helps serve the singular goal of keeping track of score information for questions on an assignment for a given participant. We have also improved the maintainability of the code by making our methods more atomic which should promote extension outside of our methods for new functionality satisfying the Open/Close principle. The remaining three principles did not really apply to this project as the grades_controller has minimal interactions with it's superclass and has no independent model that it controls or is responsible for governing.&lt;br /&gt;
===DRY principle===&lt;br /&gt;
To satisfy the don't repeat yourself principle we sought to make private helper methods to abstract repeated code that was adding complexity to our methods.  One such method is the get_data_for_heat_map method which replaces a substantial amount of what used to be complex and repeated code, which has now been significantly simplified for readability.  Please see the snippet below for the new method, it's primary goal is to set the instance variables of the controller as needed so we can prepare data for the heat map as needed in the front end.  We also relocated complex code that did not aid in the readability into helper methods which have also been refactored, the main goal of this was to promote readability in the main endpoint methods remove unnecessary clutter from the code, and limit code repetition in future modifications by providing modular helper methods for functionality that we believe may need to be repeated in future enhancements such as listing the questions or querying review grades.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Provides data for the heat maps in the view statements&lt;br /&gt;
  def get_data_for_heat_map(id)&lt;br /&gt;
    # Finds the assignment&lt;br /&gt;
    @assignment = Assignment.find(id)&lt;br /&gt;
    # Extracts the questionnaires&lt;br /&gt;
    @questions = filter_questionnaires(@assignment)&lt;br /&gt;
    @scores = review_grades(@assignment, @questions)&lt;br /&gt;
    @review_score_count = @scores[:teams].length # After rejecting nil scores need original length to iterate over hash&lt;br /&gt;
    @averages = vector(@scores)&lt;br /&gt;
    @avg_of_avg = mean(@averages)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Testing Details===&lt;br /&gt;
The test file can be located at:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spec/requests/api/v1/grades_controller_spec.rb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''action_allowed'''&lt;br /&gt;
** Passes in the view action and an assignment we wish to view. Determines if the user has the appropriate permissions to view it.&lt;br /&gt;
*'''view'''&lt;br /&gt;
** Passes in the id of the assignment and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''view_team'''&lt;br /&gt;
** Pasess in the assignment id and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''edit'''&lt;br /&gt;
** Passes in the id of the assignment and expects the participant's id, the same assignment's id, '''questions''', and '''scores'''.&lt;br /&gt;
*'''instructor_review'''&lt;br /&gt;
** Passes in the id of a participant and expects '''controller''', '''action''', the same participant id, and the instructor.&lt;br /&gt;
*'''update'''&lt;br /&gt;
** Passes in a participant id and a body which contains '''grade_for_submission''' (integer) and '''comment_for_submission''' (string). Expects the same grade, comment, '''action''', and participant's id.&lt;br /&gt;
&lt;br /&gt;
'''Rswag UI'''&lt;br /&gt;
[[File:Grades_controller_test_fall_2024.png|700px|An image showing the rswag ui of accepted test results.]]&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;br /&gt;
&lt;br /&gt;
==Previous Iterations==&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158258</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158258"/>
		<updated>2024-10-30T02:32:17Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
===[https://drive.google.com/file/d/1lgFLevdhs7PTFpibxflQfB45nOXW04jA/view?usp=sharing Swagger Video Submission]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents. Additionally, we will be testing the controller with rswag.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor '''grade_controller.rb''', which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment, and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;API::V1::GradesController&amp;lt;/code&amp;gt; utilizes action-based permissions through '''action_allowed''' to provide broader functionality to instructors versus students. With the frontend systems of the Grades Controller relying on heat map systems, '''view''' and '''view_team''' provide the detailed grading information to populate them (on the student perspective reviewer identities are kept hidden). The '''edit''' method gets the relevant assignment to be modified by the frontend view. For accessing reviews, '''instructor_review''' is utilized, leading to access of previous reviews or instantiating new ones. Finally, grade changes are saved through the '''update''' function which additionally covers comment feedback. &lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's POV, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's POV which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's POV&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
===Rationale for Changes===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
|-&lt;br /&gt;
|Added a new suite of API endpoint tests that are compatible with Rswag and tested our API endpoints thoroughly, additionally added factories for several projects in the system.&lt;br /&gt;
|As with any software change in a large system, testing is extremely important, so we wrote comprehensive tests for our endpoints.  Additionally, since the grades_controller is dependent on many other models (mainly because there is no grades model).  These changes will help future projects by providing factory methods for various models that did not currently have them in the system which should make testing for other groups easier in the future.&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Code Snippet===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Determines if the current user is able to perform :action as specified by the path parameter&lt;br /&gt;
  # If the user has the role of TA or higher they are granted access to all operations beyond view_team&lt;br /&gt;
  # Uses a switch statement for easy maintainability if added functionality is ever needed for students or&lt;br /&gt;
  # additional roles, to add more functionality simply add additional switch cases in the same syntax with&lt;br /&gt;
  # case 'action' and then some boolean check determining if that is allowed or forbidden.&lt;br /&gt;
  # GET /api/v1/grades/:action/action_allowed&lt;br /&gt;
  def action_allowed&lt;br /&gt;
    permitted = case params[:action]&lt;br /&gt;
                when 'view_team'&lt;br /&gt;
                  view_team_allowed?&lt;br /&gt;
                else&lt;br /&gt;
                  user_ta_privileges?&lt;br /&gt;
                end&lt;br /&gt;
    render json: { allowed: permitted }, status: permitted ? :ok : :forbidden&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides the needed functionality of querying needed values from the backend db and returning them to build the&lt;br /&gt;
  # heat map in the frontend from the TA/staff view.  These values are set in the get_data_for_heat_map method&lt;br /&gt;
  # which takes the assignment id as a parameter.&lt;br /&gt;
  # GET /api/v1/grades/:id/view&lt;br /&gt;
  def view&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    render json: { scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                   review_score_count: @review_score_count }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides all relevant data for the student perspective for the heat map page as well as the&lt;br /&gt;
  # needed information to showcase the questionnaires from the student view.  Additionally, handles the removal of user&lt;br /&gt;
  # identification in the reviews within the hide_reviewers_rom_student method.&lt;br /&gt;
  # GET /api/v1/grades/:id/view_team&lt;br /&gt;
  def view_team&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    @scores[:participants] = hide_reviewers_from_student&lt;br /&gt;
    questionnaires = @assignment.questionnaires&lt;br /&gt;
    questions = retrieve_questions(questionnaires, @assignment.id)&lt;br /&gt;
    render json: {scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                  review_score_count: @review_score_count, questions: questions }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Sets information required for editing the grade information, this includes the participant, questions, scores, and&lt;br /&gt;
  # assignment&lt;br /&gt;
  # GET /api/v1/grades/:id/edit&lt;br /&gt;
  def edit&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: {message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot;}, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    questions = list_questions(assignment)&lt;br /&gt;
    scores = review_grades(assignment, questions)&lt;br /&gt;
    render json: {participant: participant, questions: questions, scores: scores, assignment: assignment}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides functionality that handles informing the frontend which controller and action to direct to for instructor&lt;br /&gt;
  # review given the current state of the system.  The intended controller to handle the creation or editing of a review&lt;br /&gt;
  # is the response controller, however this method just determines if a new review must be made based on figuring out&lt;br /&gt;
  # whether or not an associated review_mapping exists from the participant already.  If one does they should go to&lt;br /&gt;
  # Response#edit and if one does not they should go to Response#new.  Only ever returns a status of ok.&lt;br /&gt;
  # GET /api/v1/grades/:id/instructor_review&lt;br /&gt;
  def instructor_review&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: { message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot; }, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    review_mapping = find_participant_review_mapping(participant)&lt;br /&gt;
    if review_mapping.new_record?&lt;br /&gt;
      render json: { controller: 'response', action: 'new', id: review_mapping.map_id,&lt;br /&gt;
                     return: 'instructor'}, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      review = Response.find_by(map_id: review_mapping.map_id)&lt;br /&gt;
      render json: { controller: 'response', action: 'edit', id: review.id, return: 'instructor'}, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Update method for the grade associated with a team, allows an instructor to upgrade a team's grade with a grade&lt;br /&gt;
  # and a comment on their assignment for submission.  The team is then saved with this change in order to be accessed&lt;br /&gt;
  # elsewhere in the code for needed scoring evaluations.  If a failure occurs while saving the team then this will&lt;br /&gt;
  # return a bad_request response complete with a message and the global ERROR_INFO which can be set elsewhere for&lt;br /&gt;
  # further error handling mechanisms&lt;br /&gt;
  # PATCH /api/v1/grades/:participant_id/update/:grade_for_submission&lt;br /&gt;
  def update&lt;br /&gt;
    participant = AssignmentParticipant.find_by(id: params[:participant_id])&lt;br /&gt;
&lt;br /&gt;
    team = participant.team&lt;br /&gt;
    team.grade_for_submission = params[:grade_for_submission]&lt;br /&gt;
    team.comment_for_submission = params[:comment_for_submission]&lt;br /&gt;
    begin&lt;br /&gt;
      team.save&lt;br /&gt;
    rescue StandardError =&amp;gt; e&lt;br /&gt;
      render json: {message: &amp;quot;Error occurred while updating grade for team #{team.id}&amp;quot;,&lt;br /&gt;
                    error: e.message }, status: :bad_request&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: { controller: 'grades', action: 'view_team', id: participant.id}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Testing Details===&lt;br /&gt;
The test file can be located at:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spec/requests/api/v1/grades_controller_spec.rb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''action_allowed'''&lt;br /&gt;
** Passes in the view action and an assignment we wish to view. Determines if the user has the appropriate permissions to view it.&lt;br /&gt;
*'''view'''&lt;br /&gt;
** Passes in the id of the assignment and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''view_team'''&lt;br /&gt;
** Pasess in the assignment id and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''edit'''&lt;br /&gt;
** Passes in the id of the assignment and expects the participant's id, the same assignment's id, '''questions''', and '''scores'''.&lt;br /&gt;
*'''instructor_review'''&lt;br /&gt;
** Passes in the id of a participant and expects '''controller''', '''action''', the same participant id, and the instructor.&lt;br /&gt;
*'''update'''&lt;br /&gt;
** Passes in a participant id and a body which contains '''grade_for_submission''' (integer) and '''comment_for_submission''' (string). Expects the same grade, comment, '''action''', and participant's id.&lt;br /&gt;
&lt;br /&gt;
'''Rswag UI'''&lt;br /&gt;
[[File:Grades_controller_test_fall_2024.png|700px|An image showing the rswag ui of accepted test results.]]&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;br /&gt;
&lt;br /&gt;
==Previous Iterations==&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158189</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158189"/>
		<updated>2024-10-30T02:15:26Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
===[https://drive.google.com/file/d/1lgFLevdhs7PTFpibxflQfB45nOXW04jA/view?usp=sharing Swagger Video Submission]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents.&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor '''grade_controller.rb''', which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment, and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's POV, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's POV which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's POV&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
===Rationale for Changes===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
|-&lt;br /&gt;
|Added a new suite of API endpoint tests that are compatible with Rswag and tested our API endpoints thoroughly, additionally added factories for several projects in the system.&lt;br /&gt;
|As with any software change in a large system, testing is extremely important, so we wrote comprehensive tests for our endpoints.  Additionally, since the grades_controller is dependent on many other models (mainly because there is no grades model).  These changes will help future projects by providing factory methods for various models that did not currently have them in the system which should make testing for other groups easier in the future.&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Code Snippet===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Determines if the current user is able to perform :action as specified by the path parameter&lt;br /&gt;
  # If the user has the role of TA or higher they are granted access to all operations beyond view_team&lt;br /&gt;
  # Uses a switch statement for easy maintainability if added functionality is ever needed for students or&lt;br /&gt;
  # additional roles, to add more functionality simply add additional switch cases in the same syntax with&lt;br /&gt;
  # case 'action' and then some boolean check determining if that is allowed or forbidden.&lt;br /&gt;
  # GET /api/v1/grades/:action/action_allowed&lt;br /&gt;
  def action_allowed&lt;br /&gt;
    permitted = case params[:action]&lt;br /&gt;
                when 'view_team'&lt;br /&gt;
                  view_team_allowed?&lt;br /&gt;
                else&lt;br /&gt;
                  user_ta_privileges?&lt;br /&gt;
                end&lt;br /&gt;
    render json: { allowed: permitted }, status: permitted ? :ok : :forbidden&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides the needed functionality of querying needed values from the backend db and returning them to build the&lt;br /&gt;
  # heat map in the frontend from the TA/staff view.  These values are set in the get_data_for_heat_map method&lt;br /&gt;
  # which takes the assignment id as a parameter.&lt;br /&gt;
  # GET /api/v1/grades/:id/view&lt;br /&gt;
  def view&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    render json: { scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                   review_score_count: @review_score_count }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides all relevant data for the student perspective for the heat map page as well as the&lt;br /&gt;
  # needed information to showcase the questionnaires from the student view.  Additionally, handles the removal of user&lt;br /&gt;
  # identification in the reviews within the hide_reviewers_rom_student method.&lt;br /&gt;
  # GET /api/v1/grades/:id/view_team&lt;br /&gt;
  def view_team&lt;br /&gt;
    get_data_for_heat_map(params[:id])&lt;br /&gt;
    @scores[:participants] = hide_reviewers_from_student&lt;br /&gt;
    questionnaires = @assignment.questionnaires&lt;br /&gt;
    questions = retrieve_questions(questionnaires, @assignment.id)&lt;br /&gt;
    render json: {scores: @scores, assignment: @assignment, averages: @averages, avg_of_avg: @avg_of_avg,&lt;br /&gt;
                  review_score_count: @review_score_count, questions: questions }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Sets information required for editing the grade information, this includes the participant, questions, scores, and&lt;br /&gt;
  # assignment&lt;br /&gt;
  # GET /api/v1/grades/:id/edit&lt;br /&gt;
  def edit&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: {message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot;}, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    questions = list_questions(assignment)&lt;br /&gt;
    scores = review_grades(assignment, questions)&lt;br /&gt;
    render json: {participant: participant, questions: questions, scores: scores, assignment: assignment}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Provides functionality that handles informing the frontend which controller and action to direct to for instructor&lt;br /&gt;
  # review given the current state of the system.  The intended controller to handle the creation or editing of a review&lt;br /&gt;
  # is the response controller, however this method just determines if a new review must be made based on figuring out&lt;br /&gt;
  # whether or not an associated review_mapping exists from the participant already.  If one does they should go to&lt;br /&gt;
  # Response#edit and if one does not they should go to Response#new.  Only ever returns a status of ok.&lt;br /&gt;
  # GET /api/v1/grades/:id/instructor_review&lt;br /&gt;
  def instructor_review&lt;br /&gt;
    begin&lt;br /&gt;
      participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: { message: &amp;quot;Assignment participant #{params[:id]} not found&amp;quot; }, status: :not_found&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    review_mapping = find_participant_review_mapping(participant)&lt;br /&gt;
    if review_mapping.new_record?&lt;br /&gt;
      render json: { controller: 'response', action: 'new', id: review_mapping.map_id,&lt;br /&gt;
                     return: 'instructor'}, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      review = Response.find_by(map_id: review_mapping.map_id)&lt;br /&gt;
      render json: { controller: 'response', action: 'edit', id: review.id, return: 'instructor'}, status: :ok&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Update method for the grade associated with a team, allows an instructor to upgrade a team's grade with a grade&lt;br /&gt;
  # and a comment on their assignment for submission.  The team is then saved with this change in order to be accessed&lt;br /&gt;
  # elsewhere in the code for needed scoring evaluations.  If a failure occurs while saving the team then this will&lt;br /&gt;
  # return a bad_request response complete with a message and the global ERROR_INFO which can be set elsewhere for&lt;br /&gt;
  # further error handling mechanisms&lt;br /&gt;
  # PATCH /api/v1/grades/:participant_id/update/:grade_for_submission&lt;br /&gt;
  def update&lt;br /&gt;
    participant = AssignmentParticipant.find_by(id: params[:participant_id])&lt;br /&gt;
&lt;br /&gt;
    team = participant.team&lt;br /&gt;
    team.grade_for_submission = params[:grade_for_submission]&lt;br /&gt;
    team.comment_for_submission = params[:comment_for_submission]&lt;br /&gt;
    begin&lt;br /&gt;
      team.save&lt;br /&gt;
    rescue StandardError =&amp;gt; e&lt;br /&gt;
      render json: {message: &amp;quot;Error occurred while updating grade for team #{team.id}&amp;quot;,&lt;br /&gt;
                    error: e.message }, status: :bad_request&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: { controller: 'grades', action: 'view_team', id: participant.id}, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Testing Details===&lt;br /&gt;
The test file can be located at:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spec/requests/api/v1/grades_controller_spec.rb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''action_allowed'''&lt;br /&gt;
** Passes in the view action and an assignment we wish to view. Determines if the user has the appropriate permissions to view it.&lt;br /&gt;
*'''view'''&lt;br /&gt;
** Passes in the id of the assignment and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''view_team'''&lt;br /&gt;
** Pasess in the assignment id and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''edit'''&lt;br /&gt;
** Passes in the id of the assignment and expects the participant's id, the same assignment's id, '''questions''', and '''scores'''.&lt;br /&gt;
*'''instructor_review'''&lt;br /&gt;
** Passes in the id of a participant and expects '''controller''', '''action''', the same participant id, and the instructor.&lt;br /&gt;
*'''update'''&lt;br /&gt;
** Passes in a participant id and a body which contains '''grade_for_submission''' (integer) and '''comment_for_submission''' (string). Expects the same grade, comment, '''action''', and participant's id.&lt;br /&gt;
&lt;br /&gt;
'''Rswag UI'''&lt;br /&gt;
[[File:Grades_controller_test_fall_2024.png|700px|An image showing the rswag ui of accepted test results.]]&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;br /&gt;
&lt;br /&gt;
==Previous Iterations==&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158164</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158164"/>
		<updated>2024-10-30T02:08:43Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
===[https://drive.google.com/file/d/1lgFLevdhs7PTFpibxflQfB45nOXW04jA/view?usp=sharing Swagger Video Submission]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents.&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor '''grade_controller.rb''', which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment, and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's POV, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's POV which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's POV&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
! Relevant commit(s)&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/da9ec47222ba52f1ff675723a4d4fa051b4393e6 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/f9c353fad8e62e556398b0ec6905348ae7c35d36 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/1dcb5a1d124c1319757e8cea7c02c6a6d19e7cf7 Commit Link 2]&lt;br /&gt;
|-&lt;br /&gt;
|Added a new suite of API endpoint tests that are compatible with Rswag and tested our API endpoints thoroughly, additionally added factories for several projects in the system.&lt;br /&gt;
|As with any software change in a large system, testing is extremely important, so we wrote comprehensive tests for our endpoints.  Additionally, since the grades_controller is dependent on many other models (mainly because there is no grades model).  These changes will help future projects by providing factory methods for various models that did not currently have them in the system which should make testing for other groups easier in the future.&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/13e23163e84a5255547d218b316b86836473c1ff Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/0731245f40bab6376313672f39bf66e2f9d7d427 Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/e8d14390fbeedbc0748a695c121b787b53867727 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/28e5212bec820b9e92b449d0b84edee77bbbdf79 Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/a82bf077613077eb89d5a6ce0c7adc903d93c674 Commit Link 6] [https://github.com/expertiza/reimplementation-back-end/commit/385ab059443b9599d0abb4474d01b830116cb06f Commit Link 7] [https://github.com/expertiza/reimplementation-back-end/commit/7e8c53109d09f7dc4ce5d8074f56cfbc64614ba1 Commit Link 8] [https://github.com/expertiza/reimplementation-back-end/commit/bf569bcb662a35f0a30b83d28c8650bddea902d5 Commit Link 9] [https://github.com/expertiza/reimplementation-back-end/commit/8ca62a8d55d4a4729a2eabda2ae3a2341ac4038c Commit Link 10]&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/911d861a634d69bf8056698249be70e85db186e9  Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/a374d3b5aa4d6dbc618dc2984633939f7c2dde7b Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/c524f1cfa36b74b7cfeceae68f6c81259f82c0ee Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/37866b6abeaea1da01dd52fb211e0cde5e6584c4 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/911d861a634d69bf8056698249be70e85db186e9 Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/8323c30038f3bb05611b8ce2262e889194135f44 Commit Link 6]&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/182337179691819f9e16c985ceee4c20c3a5efcd Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/68272005c0a60e3a1476b2b69fec2372c915fd7a Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/9d305d96429509462058c772fed7cf9b069edc08 Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/141476315f950cdf6dd1ee777230c23313c4048e Commit Link 4]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Testing Details===&lt;br /&gt;
The test file can be located at:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spec/requests/api/v1/grades_controller_spec.rb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''action_allowed'''&lt;br /&gt;
** Passes in the view action and an assignment we wish to view. Determines if the user has the appropriate permissions to view it.&lt;br /&gt;
*'''view'''&lt;br /&gt;
** Passes in the id of the assignment and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''view_team'''&lt;br /&gt;
** Pasess in the assignment id and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''edit'''&lt;br /&gt;
** Passes in the id of the assignment and expects the participant's id, the same assignment's id, '''questions''', and '''scores'''.&lt;br /&gt;
*'''instructor_review'''&lt;br /&gt;
** Passes in the id of a participant and expects '''controller''', '''action''', the same participant id, and the instructor.&lt;br /&gt;
*'''update'''&lt;br /&gt;
** Passes in a participant id and a body which contains '''grade_for_submission''' (integer) and '''comment_for_submission''' (string). Expects the same grade, comment, '''action''', and participant's id.&lt;br /&gt;
&lt;br /&gt;
'''Rswag UI'''&lt;br /&gt;
[[File:Grades_controller_test_fall_2024.png|700px|An image showing the rswag ui of accepted test results.]]&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;br /&gt;
&lt;br /&gt;
==Previous Iterations==&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158163</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158163"/>
		<updated>2024-10-30T02:08:31Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
===[https://drive.google.com/file/d/1lgFLevdhs7PTFpibxflQfB45nOXW04jA/view?usp=sharing Swagger Video Submission]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents.&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor '''grade_controller.rb''', which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment, and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's POV, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's POV which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's POV&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
! Relevant commit(s)&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/da9ec47222ba52f1ff675723a4d4fa051b4393e6 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/f9c353fad8e62e556398b0ec6905348ae7c35d36 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/1dcb5a1d124c1319757e8cea7c02c6a6d19e7cf7 Commit Link 2]&lt;br /&gt;
|-&lt;br /&gt;
|Added a new suite of API endpoint tests that are compatible with Rswag and tested our API endpoints thoroughly, additionally added factories for several projects in the system.&lt;br /&gt;
|As with any software change in a large system, testing is extremely important, so we wrote comprehensive tests for our endpoints.  Additionally, since the grades_controller is dependent on many other models (mainly because there is no grades model).  These changes will help future projects by providing factory methods for various models that did not currently have them in the system which should make testing for other groups easier in the future.&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/13e23163e84a5255547d218b316b86836473c1ff Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/0731245f40bab6376313672f39bf66e2f9d7d427 Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/e8d14390fbeedbc0748a695c121b787b53867727 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/28e5212bec820b9e92b449d0b84edee77bbbdf79 Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/a82bf077613077eb89d5a6ce0c7adc903d93c674 Commit Link 6] [https://github.com/expertiza/reimplementation-back-end/commit/385ab059443b9599d0abb4474d01b830116cb06f Commit Link 7] [https://github.com/expertiza/reimplementation-back-end/commit/7e8c53109d09f7dc4ce5d8074f56cfbc64614ba1 Commit Link 8] [https://github.com/expertiza/reimplementation-back-end/commit/bf569bcb662a35f0a30b83d28c8650bddea902d5 Commit Link 9] [https://github.com/expertiza/reimplementation-back-end/commit/8ca62a8d55d4a4729a2eabda2ae3a2341ac4038c Commit Link 10]&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/911d861a634d69bf8056698249be70e85db186e9  Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/a374d3b5aa4d6dbc618dc2984633939f7c2dde7b Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/c524f1cfa36b74b7cfeceae68f6c81259f82c0ee Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/37866b6abeaea1da01dd52fb211e0cde5e6584c4 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/911d861a634d69bf8056698249be70e85db186e9 Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/8323c30038f3bb05611b8ce2262e889194135f44 Commit Link 6]&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/182337179691819f9e16c985ceee4c20c3a5efcd Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/68272005c0a60e3a1476b2b69fec2372c915fd7a Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/9d305d96429509462058c772fed7cf9b069edc08 Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/141476315f950cdf6dd1ee777230c23313c4048e Commit Link 4]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Testing Details===&lt;br /&gt;
The test file can be located at:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spec/requests/api/v1/grades_controller_spec.rb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''action_allowed'''&lt;br /&gt;
** Passes in the view action and an assignment we wish to view. Determines if the user has the appropriate permissions to view it.&lt;br /&gt;
*'''view'''&lt;br /&gt;
** Passes in the id of the assignment and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''view_team'''&lt;br /&gt;
** Pasess in the assignment id and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''edit'''&lt;br /&gt;
** Passes in the id of the assignment and expects the participant's id, the same assignment's id, '''questions''', and '''scores'''.&lt;br /&gt;
*'''instructor_review'''&lt;br /&gt;
** Passes in the id of a participant and expects '''controller''', '''action''', the same participant id, and the instructor.&lt;br /&gt;
*'''update'''&lt;br /&gt;
** Passes in a participant id and a body which contains '''grade_for_submission''' (integer) and '''comment_for_submission''' (string). Expects the same grade, comment, '''action''', and participant's id.&lt;br /&gt;
&lt;br /&gt;
'''Rswag UI'''&lt;br /&gt;
[[File:Grades_controller_test_fall_2024.png|700px|An image showing the rswag ui of accepted test results.]]&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;br /&gt;
&lt;br /&gt;
===Previous Iterations===&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158159</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158159"/>
		<updated>2024-10-30T02:06:09Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
===[https://drive.google.com/file/d/1lgFLevdhs7PTFpibxflQfB45nOXW04jA/view?usp=sharing Swagger Video Submission]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents.&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor '''grade_controller.rb''', which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment, and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
===Previous Iterations===&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's POV, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's POV which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's POV&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
! Relevant commit(s)&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/da9ec47222ba52f1ff675723a4d4fa051b4393e6 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/f9c353fad8e62e556398b0ec6905348ae7c35d36 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/1dcb5a1d124c1319757e8cea7c02c6a6d19e7cf7 Commit Link 2]&lt;br /&gt;
|-&lt;br /&gt;
|Added a new suite of API endpoint tests that are compatible with Rswag and tested our API endpoints thoroughly, additionally added factories for several projects in the system.&lt;br /&gt;
|As with any software change in a large system, testing is extremely important, so we wrote comprehensive tests for our endpoints.  Additionally, since the grades_controller is dependent on many other models (mainly because there is no grades model).  These changes will help future projects by providing factory methods for various models that did not currently have them in the system which should make testing for other groups easier in the future.&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/13e23163e84a5255547d218b316b86836473c1ff Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/0731245f40bab6376313672f39bf66e2f9d7d427 Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/e8d14390fbeedbc0748a695c121b787b53867727 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/28e5212bec820b9e92b449d0b84edee77bbbdf79 Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/a82bf077613077eb89d5a6ce0c7adc903d93c674 Commit Link 6] [https://github.com/expertiza/reimplementation-back-end/commit/385ab059443b9599d0abb4474d01b830116cb06f Commit Link 7] [https://github.com/expertiza/reimplementation-back-end/commit/7e8c53109d09f7dc4ce5d8074f56cfbc64614ba1 Commit Link 8] [https://github.com/expertiza/reimplementation-back-end/commit/bf569bcb662a35f0a30b83d28c8650bddea902d5 Commit Link 9] [https://github.com/expertiza/reimplementation-back-end/commit/8ca62a8d55d4a4729a2eabda2ae3a2341ac4038c Commit Link 10]&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/911d861a634d69bf8056698249be70e85db186e9  Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/a374d3b5aa4d6dbc618dc2984633939f7c2dde7b Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/c524f1cfa36b74b7cfeceae68f6c81259f82c0ee Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/37866b6abeaea1da01dd52fb211e0cde5e6584c4 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/911d861a634d69bf8056698249be70e85db186e9 Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/8323c30038f3bb05611b8ce2262e889194135f44 Commit Link 6]&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/182337179691819f9e16c985ceee4c20c3a5efcd Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/68272005c0a60e3a1476b2b69fec2372c915fd7a Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/9d305d96429509462058c772fed7cf9b069edc08 Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/141476315f950cdf6dd1ee777230c23313c4048e Commit Link 4]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Testing Details===&lt;br /&gt;
The test file can be located at:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spec/requests/api/v1/grades_controller_spec.rb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''action_allowed'''&lt;br /&gt;
** Passes in the view action and an assignment we wish to view. Determines if the user has the appropriate permissions to view it.&lt;br /&gt;
*'''view'''&lt;br /&gt;
** Passes in the id of the assignment and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''view_team'''&lt;br /&gt;
** Pasess in the assignment id and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''edit'''&lt;br /&gt;
** Passes in the id of the assignment and expects the participant's id, the same assignment's id, '''questions''', and '''scores'''.&lt;br /&gt;
*'''instructor_review'''&lt;br /&gt;
** Passes in the id of a participant and expects '''controller''', '''action''', the same participant id, and the instructor.&lt;br /&gt;
*'''update'''&lt;br /&gt;
** Passes in a participant id and a body which contains '''grade_for_submission''' (integer) and '''comment_for_submission''' (string). Expects the same grade, comment, '''action''', and participant's id.&lt;br /&gt;
&lt;br /&gt;
'''Rswag UI'''&lt;br /&gt;
[[File:Grades_controller_test_fall_2024.png|700px|An image showing the rswag ui of accepted test results.]]&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158156</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158156"/>
		<updated>2024-10-30T02:04:53Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents.&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor '''grade_controller.rb''', which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment, and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
===Previous Iterations===&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's POV, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's POV which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's POV&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
! Relevant commit(s)&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/da9ec47222ba52f1ff675723a4d4fa051b4393e6 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/f9c353fad8e62e556398b0ec6905348ae7c35d36 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/1dcb5a1d124c1319757e8cea7c02c6a6d19e7cf7 Commit Link 2]&lt;br /&gt;
|-&lt;br /&gt;
|Added a new suite of API endpoint tests that are compatible with Rswag and tested our API endpoints thoroughly, additionally added factories for several projects in the system.&lt;br /&gt;
|As with any software change in a large system, testing is extremely important, so we wrote comprehensive tests for our endpoints.  Additionally, since the grades_controller is dependent on many other models (mainly because there is no grades model).  These changes will help future projects by providing factory methods for various models that did not currently have them in the system which should make testing for other groups easier in the future.&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/13e23163e84a5255547d218b316b86836473c1ff Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/0731245f40bab6376313672f39bf66e2f9d7d427 Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/e8d14390fbeedbc0748a695c121b787b53867727 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/28e5212bec820b9e92b449d0b84edee77bbbdf79 Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/a82bf077613077eb89d5a6ce0c7adc903d93c674 Commit Link 6] [https://github.com/expertiza/reimplementation-back-end/commit/385ab059443b9599d0abb4474d01b830116cb06f Commit Link 7] [https://github.com/expertiza/reimplementation-back-end/commit/7e8c53109d09f7dc4ce5d8074f56cfbc64614ba1 Commit Link 8] [https://github.com/expertiza/reimplementation-back-end/commit/bf569bcb662a35f0a30b83d28c8650bddea902d5 Commit Link 9] [https://github.com/expertiza/reimplementation-back-end/commit/8ca62a8d55d4a4729a2eabda2ae3a2341ac4038c Commit Link 10]&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/911d861a634d69bf8056698249be70e85db186e9  Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/a374d3b5aa4d6dbc618dc2984633939f7c2dde7b Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/c524f1cfa36b74b7cfeceae68f6c81259f82c0ee Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/37866b6abeaea1da01dd52fb211e0cde5e6584c4 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/911d861a634d69bf8056698249be70e85db186e9 Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/8323c30038f3bb05611b8ce2262e889194135f44 Commit Link 6]&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/182337179691819f9e16c985ceee4c20c3a5efcd Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/68272005c0a60e3a1476b2b69fec2372c915fd7a Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/9d305d96429509462058c772fed7cf9b069edc08 Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/141476315f950cdf6dd1ee777230c23313c4048e Commit Link 4]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Testing Details===&lt;br /&gt;
The test file can be located at:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spec/requests/api/v1/grades_controller_spec.rb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''action_allowed'''&lt;br /&gt;
** Passes in the view action and an assignment we wish to view. Determines if the user has the appropriate permissions to view it.&lt;br /&gt;
*'''view'''&lt;br /&gt;
** Passes in the id of the assignment and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''view_team'''&lt;br /&gt;
** Pasess in the assignment id and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''edit'''&lt;br /&gt;
** Passes in the id of the assignment and expects the participant's id, the same assignment's id, '''questions''', and '''scores'''.&lt;br /&gt;
*'''instructor_review'''&lt;br /&gt;
** Passes in the id of a participant and expects '''controller''', '''action''', the same participant id, and the instructor.&lt;br /&gt;
*'''update'''&lt;br /&gt;
** Passes in a participant id and a body which contains '''grade_for_submission''' (integer) and '''comment_for_submission''' (string). Expects the same grade, comment, '''action''', and participant's id.&lt;br /&gt;
&lt;br /&gt;
'''Rswag UI'''&lt;br /&gt;
[[File:Grades_controller_test_fall_2024.png|700px|An image showing the rswag ui of accepted test results.]]&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158147</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158147"/>
		<updated>2024-10-30T02:03:26Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents.&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor '''grade_controller.rb''', which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment, and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
===Previous Iterations===&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's POV, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's POV which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's POV&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
! Relevant commit(s)&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/da9ec47222ba52f1ff675723a4d4fa051b4393e6 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/f9c353fad8e62e556398b0ec6905348ae7c35d36 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/1dcb5a1d124c1319757e8cea7c02c6a6d19e7cf7 Commit Link 2]&lt;br /&gt;
|-&lt;br /&gt;
|Added a new suite of API endpoint tests that are compatible with Rswag and tested our API endpoints thoroughly, additionally added factories for several projects in the system.&lt;br /&gt;
|As with any software change in a large system, testing is extremely important, so we wrote comprehensive tests for our endpoints.  Additionally, since the grades_controller is dependent on many other models (mainly because there is no grades model).  These changes will help future projects by providing factory methods for various models that did not currently have them in the system which should make testing for other groups easier in the future.&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/13e23163e84a5255547d218b316b86836473c1ff Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/0731245f40bab6376313672f39bf66e2f9d7d427 Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/e8d14390fbeedbc0748a695c121b787b53867727 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/28e5212bec820b9e92b449d0b84edee77bbbdf79 Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/a82bf077613077eb89d5a6ce0c7adc903d93c674 Commit Link 6] [https://github.com/expertiza/reimplementation-back-end/commit/385ab059443b9599d0abb4474d01b830116cb06f Commit Link 7] [https://github.com/expertiza/reimplementation-back-end/commit/7e8c53109d09f7dc4ce5d8074f56cfbc64614ba1 Commit Link 8] [https://github.com/expertiza/reimplementation-back-end/commit/bf569bcb662a35f0a30b83d28c8650bddea902d5 Commit Link 9] [https://github.com/expertiza/reimplementation-back-end/commit/8ca62a8d55d4a4729a2eabda2ae3a2341ac4038c Commit Link 10]&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/911d861a634d69bf8056698249be70e85db186e9  Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/a374d3b5aa4d6dbc618dc2984633939f7c2dde7b Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/c524f1cfa36b74b7cfeceae68f6c81259f82c0ee Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/37866b6abeaea1da01dd52fb211e0cde5e6584c4 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/911d861a634d69bf8056698249be70e85db186e9 Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/8323c30038f3bb05611b8ce2262e889194135f44 Commit Link 6]&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/182337179691819f9e16c985ceee4c20c3a5efcd Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/68272005c0a60e3a1476b2b69fec2372c915fd7a Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/9d305d96429509462058c772fed7cf9b069edc08 &lt;br /&gt;
https://github.com/expertiza/reimplementation-back-end/commit/141476315f950cdf6dd1ee777230c23313c4048e Commit Link 3]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Testing Details===&lt;br /&gt;
The test file can be located at:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spec/requests/api/v1/grades_controller_spec.rb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''action_allowed'''&lt;br /&gt;
** Passes in the view action and an assignment we wish to view. Determines if the user has the appropriate permissions to view it.&lt;br /&gt;
*'''view'''&lt;br /&gt;
** Passes in the id of the assignment and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''view_team'''&lt;br /&gt;
** Pasess in the assignment id and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''edit'''&lt;br /&gt;
** Passes in the id of the assignment and expects the participant's id, the same assignment's id, '''questions''', and '''scores'''.&lt;br /&gt;
*'''instructor_review'''&lt;br /&gt;
** Passes in the id of a participant and expects '''controller''', '''action''', the same participant id, and the instructor.&lt;br /&gt;
*'''update'''&lt;br /&gt;
** Passes in a participant id and a body which contains '''grade_for_submission''' (integer) and '''comment_for_submission''' (string). Expects the same grade, comment, '''action''', and participant's id.&lt;br /&gt;
&lt;br /&gt;
'''Rswag UI'''&lt;br /&gt;
[[File:Grades_controller_test_fall_2024.png|700px|An image showing the rswag ui of accepted test results.]]&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158144</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158144"/>
		<updated>2024-10-30T02:01:57Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents.&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor '''grade_controller.rb''', which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment, and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
===Previous Iterations===&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's POV, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's POV which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's POV&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
! Relevant commit(s)&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/da9ec47222ba52f1ff675723a4d4fa051b4393e6 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/f9c353fad8e62e556398b0ec6905348ae7c35d36 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/1dcb5a1d124c1319757e8cea7c02c6a6d19e7cf7 Commit Link 2]&lt;br /&gt;
|-&lt;br /&gt;
|Added a new suite of API endpoint tests that are compatible with Rswag and tested our API endpoints thoroughly, additionally added factories for several projects in the system.&lt;br /&gt;
|As with any software change in a large system, testing is extremely important, so we wrote comprehensive tests for our endpoints.  Additionally, since the grades_controller is dependent on many other models (mainly because there is no grades model).  These changes will help future projects by providing factory methods for various models that did not currently have them in the system which should make testing for other groups easier in the future.&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/13e23163e84a5255547d218b316b86836473c1ff Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/0731245f40bab6376313672f39bf66e2f9d7d427 Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/e8d14390fbeedbc0748a695c121b787b53867727 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/28e5212bec820b9e92b449d0b84edee77bbbdf79 Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/a82bf077613077eb89d5a6ce0c7adc903d93c674 Commit Link 6] [https://github.com/expertiza/reimplementation-back-end/commit/385ab059443b9599d0abb4474d01b830116cb06f Commit Link 7] [https://github.com/expertiza/reimplementation-back-end/commit/7e8c53109d09f7dc4ce5d8074f56cfbc64614ba1 Commit Link 8] [https://github.com/expertiza/reimplementation-back-end/commit/bf569bcb662a35f0a30b83d28c8650bddea902d5 Commit Link 9] [https://github.com/expertiza/reimplementation-back-end/commit/8ca62a8d55d4a4729a2eabda2ae3a2341ac4038c Commit Link 10]&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/911d861a634d69bf8056698249be70e85db186e9  Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/a374d3b5aa4d6dbc618dc2984633939f7c2dde7b Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/c524f1cfa36b74b7cfeceae68f6c81259f82c0ee Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/37866b6abeaea1da01dd52fb211e0cde5e6584c4 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/911d861a634d69bf8056698249be70e85db186e9 Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/8323c30038f3bb05611b8ce2262e889194135f44 Commit Link 6]&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|WIP&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Testing Details===&lt;br /&gt;
The test file can be located at:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spec/requests/api/v1/grades_controller_spec.rb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''action_allowed'''&lt;br /&gt;
** Passes in the view action and an assignment we wish to view. Determines if the user has the appropriate permissions to view it.&lt;br /&gt;
*'''view'''&lt;br /&gt;
** Passes in the id of the assignment and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''view_team'''&lt;br /&gt;
** Pasess in the assignment id and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''edit'''&lt;br /&gt;
** Passes in the id of the assignment and expects the participant's id, the same assignment's id, '''questions''', and '''scores'''.&lt;br /&gt;
*'''instructor_review'''&lt;br /&gt;
** Passes in the id of a participant and expects '''controller''', '''action''', the same participant id, and the instructor.&lt;br /&gt;
*'''update'''&lt;br /&gt;
** Passes in a participant id and a body which contains '''grade_for_submission''' (integer) and '''comment_for_submission''' (string). Expects the same grade, comment, '''action''', and participant's id.&lt;br /&gt;
&lt;br /&gt;
'''Rswag UI'''&lt;br /&gt;
[[File:Grades_controller_test_fall_2024.png|700px|An image showing the rswag ui of accepted test results.]]&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158142</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158142"/>
		<updated>2024-10-30T02:00:19Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents.&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor '''grade_controller.rb''', which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment, and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
===Previous Iterations===&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's POV, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's POV which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's POV&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
! Relevant commit(s)&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/da9ec47222ba52f1ff675723a4d4fa051b4393e6 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/f9c353fad8e62e556398b0ec6905348ae7c35d36 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/1dcb5a1d124c1319757e8cea7c02c6a6d19e7cf7 Commit Link 2]&lt;br /&gt;
|-&lt;br /&gt;
|Created test files and factories to test our grades controller reimplementation.&lt;br /&gt;
|We needed to test the API endpoints for the grades controller. The factories helped in assisting the testing.&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/7ae2684a72dfd34706f77f4da62cf3bea06dab92 Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/e8d14390fbeedbc0748a695c121b787b53867727 Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/28e5212bec820b9e92b449d0b84edee77bbbdf79 Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/a82bf077613077eb89d5a6ce0c7adc903d93c674 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/385ab059443b9599d0abb4474d01b830116cb06f Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/7e8c53109d09f7dc4ce5d8074f56cfbc64614ba1 Commit Link 6]&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/911d861a634d69bf8056698249be70e85db186e9  Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/a374d3b5aa4d6dbc618dc2984633939f7c2dde7b Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/c524f1cfa36b74b7cfeceae68f6c81259f82c0ee Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/37866b6abeaea1da01dd52fb211e0cde5e6584c4 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/911d861a634d69bf8056698249be70e85db186e9 Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/8323c30038f3bb05611b8ce2262e889194135f44 Commit Link 6]&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/13e23163e84a5255547d218b316b86836473c1ff Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/0731245f40bab6376313672f39bf66e2f9d7d427 Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/e8d14390fbeedbc0748a695c121b787b53867727 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/28e5212bec820b9e92b449d0b84edee77bbbdf79 Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/a82bf077613077eb89d5a6ce0c7adc903d93c674 Commit Link 6] [https://github.com/expertiza/reimplementation-back-end/commit/385ab059443b9599d0abb4474d01b830116cb06f Commit Link 7] [https://github.com/expertiza/reimplementation-back-end/commit/7e8c53109d09f7dc4ce5d8074f56cfbc64614ba1 Commit Link 8] [https://github.com/expertiza/reimplementation-back-end/commit/bf569bcb662a35f0a30b83d28c8650bddea902d5 Commit Link 9] [https://github.com/expertiza/reimplementation-back-end/commit/8ca62a8d55d4a4729a2eabda2ae3a2341ac4038c Commit Link 10]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Testing Details===&lt;br /&gt;
The test file can be located at:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spec/requests/api/v1/grades_controller_spec.rb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''action_allowed'''&lt;br /&gt;
** Passes in the view action and an assignment we wish to view. Determines if the user has the appropriate permissions to view it.&lt;br /&gt;
*'''view'''&lt;br /&gt;
** Passes in the id of the assignment and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''view_team'''&lt;br /&gt;
** Pasess in the assignment id and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''edit'''&lt;br /&gt;
** Passes in the id of the assignment and expects the participant's id, the same assignment's id, '''questions''', and '''scores'''.&lt;br /&gt;
*'''instructor_review'''&lt;br /&gt;
** Passes in the id of a participant and expects '''controller''', '''action''', the same participant id, and the instructor.&lt;br /&gt;
*'''update'''&lt;br /&gt;
** Passes in a participant id and a body which contains '''grade_for_submission''' (integer) and '''comment_for_submission''' (string). Expects the same grade, comment, '''action''', and participant's id.&lt;br /&gt;
&lt;br /&gt;
'''Rswag UI'''&lt;br /&gt;
[[File:Grades_controller_test_fall_2024.png|700px|An image showing the rswag ui of accepted test results.]]&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Grades_controller_test_fall_2024.png&amp;diff=158134</id>
		<title>File:Grades controller test fall 2024.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Grades_controller_test_fall_2024.png&amp;diff=158134"/>
		<updated>2024-10-30T01:57:39Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: An image showing the rswag ui of accepted test results.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
An image showing the rswag ui of accepted test results.&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158120</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158120"/>
		<updated>2024-10-30T01:53:02Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents.&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor '''grade_controller.rb''', which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment, and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
===Previous Iterations===&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's POV, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's POV which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's POV&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
! Relevant commit(s)&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/da9ec47222ba52f1ff675723a4d4fa051b4393e6 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/f9c353fad8e62e556398b0ec6905348ae7c35d36 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/1dcb5a1d124c1319757e8cea7c02c6a6d19e7cf7 Commit Link 2]&lt;br /&gt;
|-&lt;br /&gt;
|Created test files and factories to test our grades controller reimplementation.&lt;br /&gt;
|We needed to test the API endpoints for the grades controller. The factories helped in assisting the testing.&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/7ae2684a72dfd34706f77f4da62cf3bea06dab92 Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/e8d14390fbeedbc0748a695c121b787b53867727 Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/28e5212bec820b9e92b449d0b84edee77bbbdf79 Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/a82bf077613077eb89d5a6ce0c7adc903d93c674 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/385ab059443b9599d0abb4474d01b830116cb06f Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/7e8c53109d09f7dc4ce5d8074f56cfbc64614ba1 Commit Link 6]&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/911d861a634d69bf8056698249be70e85db186e9  Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/a374d3b5aa4d6dbc618dc2984633939f7c2dde7b Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/c524f1cfa36b74b7cfeceae68f6c81259f82c0ee Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/37866b6abeaea1da01dd52fb211e0cde5e6584c4 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/911d861a634d69bf8056698249be70e85db186e9 Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/8323c30038f3bb05611b8ce2262e889194135f44 Commit Link 6]&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/13e23163e84a5255547d218b316b86836473c1ff Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/0731245f40bab6376313672f39bf66e2f9d7d427 Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/e8d14390fbeedbc0748a695c121b787b53867727 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/28e5212bec820b9e92b449d0b84edee77bbbdf79 Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/a82bf077613077eb89d5a6ce0c7adc903d93c674 Commit Link 6] [https://github.com/expertiza/reimplementation-back-end/commit/385ab059443b9599d0abb4474d01b830116cb06f Commit Link 7] [https://github.com/expertiza/reimplementation-back-end/commit/7e8c53109d09f7dc4ce5d8074f56cfbc64614ba1 Commit Link 8] [https://github.com/expertiza/reimplementation-back-end/commit/bf569bcb662a35f0a30b83d28c8650bddea902d5 Commit Link 9] [https://github.com/expertiza/reimplementation-back-end/commit/8ca62a8d55d4a4729a2eabda2ae3a2341ac4038c Commit Link 10]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Testing Details===&lt;br /&gt;
* The test file can be located at:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spec/requests/api/v1/grades_controller_spec.rb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''action_allowed'''&lt;br /&gt;
** Passes in the view action and an assignment we wish to view. Determines if the user has the appropriate permissions to view it.&lt;br /&gt;
*'''view'''&lt;br /&gt;
** Passes in the id of the assignment and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''view_team'''&lt;br /&gt;
** Pasess in the assignment id and expects the '''scores''', '''averages''', '''avg_of_avg''', '''review_score_count'''.&lt;br /&gt;
*'''edit'''&lt;br /&gt;
** Passes in the id of the assignment and expects the participant's id, the same assignment's id, '''questions''', and '''scores'''.&lt;br /&gt;
*'''instructor_review'''&lt;br /&gt;
** Passes in the id of a participant and expects '''controller''', '''action''', the same participant id, and the instructor.&lt;br /&gt;
*'''update'''&lt;br /&gt;
** Passes in a participant id and a body which contains '''grade_for_submission''' (integer) and '''comment_for_submission''' (string). Expects the same grade, comment, '''action''', and participant's id.&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158065</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158065"/>
		<updated>2024-10-30T01:31:27Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents.&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor '''grade_controller.rb''', which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment, and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
===Previous Iterations===&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's POV, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's POV which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's POV&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
! Relevant commit(s)&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/da9ec47222ba52f1ff675723a4d4fa051b4393e6 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/f9c353fad8e62e556398b0ec6905348ae7c35d36 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/1dcb5a1d124c1319757e8cea7c02c6a6d19e7cf7 Commit Link 2]&lt;br /&gt;
|-&lt;br /&gt;
|Created test files and factories to test our grades controller reimplementation.&lt;br /&gt;
|We needed to test the API endpoints for the grades controller. The factories helped in assisting the testing.&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/7ae2684a72dfd34706f77f4da62cf3bea06dab92 Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/e8d14390fbeedbc0748a695c121b787b53867727 Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/28e5212bec820b9e92b449d0b84edee77bbbdf79 Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/a82bf077613077eb89d5a6ce0c7adc903d93c674 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/385ab059443b9599d0abb4474d01b830116cb06f Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/7e8c53109d09f7dc4ce5d8074f56cfbc64614ba1 Commit Link 6]&lt;br /&gt;
|-&lt;br /&gt;
|Refactored all the main API endpoint methods, added new helper methods, and removed redundant methods&lt;br /&gt;
|Many of the methods were redundant and unused in the front end (all the chart methods). We removed all of those methods and reimplemented the logic for the view methods, as previously they did grade calculation within the '''grades_controller''', something that does not follow the best programming practices. Instead, we have the calculated elsewhere and just have '''grades_controller''' displaying all the heat map information on the front end&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/911d861a634d69bf8056698249be70e85db186e9  Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/a374d3b5aa4d6dbc618dc2984633939f7c2dde7b Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/c524f1cfa36b74b7cfeceae68f6c81259f82c0ee Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/37866b6abeaea1da01dd52fb211e0cde5e6584c4 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/911d861a634d69bf8056698249be70e85db186e9 Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/8323c30038f3bb05611b8ce2262e889194135f44 Commit Link 6]&lt;br /&gt;
|-&lt;br /&gt;
|Overhauled method comment documentation replaced with correct comments that describe what the method does, and did a quick style pass to ensure code readability&lt;br /&gt;
|A lot of the comments within the '''grades_controller''' were not very good, some of which were outright incorrect or at the very least we're not correct to the current implementation of the controller at the time that we started it.  So updating all of the documentation to be accurate and reflect the current state of the controller after our changes was a necessity, trying to aim for a high understanding of what each method does without even needing to read the code for future work on the codebase.  Additionally, code readability was an issue in the old controller, primarily due to long or dense lines, we made an effort to limit these issues and promote clean, readable, and maintainable code.&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/13e23163e84a5255547d218b316b86836473c1ff Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/0731245f40bab6376313672f39bf66e2f9d7d427 Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/e8d14390fbeedbc0748a695c121b787b53867727 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/28e5212bec820b9e92b449d0b84edee77bbbdf79 Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/a82bf077613077eb89d5a6ce0c7adc903d93c674 Commit Link 6] [https://github.com/expertiza/reimplementation-back-end/commit/385ab059443b9599d0abb4474d01b830116cb06f Commit Link 7] [https://github.com/expertiza/reimplementation-back-end/commit/7e8c53109d09f7dc4ce5d8074f56cfbc64614ba1 Commit Link 8] [https://github.com/expertiza/reimplementation-back-end/commit/bf569bcb662a35f0a30b83d28c8650bddea902d5 Commit Link 9] [https://github.com/expertiza/reimplementation-back-end/commit/8ca62a8d55d4a4729a2eabda2ae3a2341ac4038c Commit Link 10]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158022</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158022"/>
		<updated>2024-10-30T01:18:08Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents.&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor '''grade_controller.rb''', which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment, and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
===Previous Iterations===&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's POV, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's POV which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's POV&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
! Relevant commit(s)&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/da9ec47222ba52f1ff675723a4d4fa051b4393e6 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/f9c353fad8e62e556398b0ec6905348ae7c35d36 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/1dcb5a1d124c1319757e8cea7c02c6a6d19e7cf7 Commit Link 2]&lt;br /&gt;
|-&lt;br /&gt;
|Created test files and factories to test our grades controller reimplementation.&lt;br /&gt;
|We needed to test the API endpoints for the grades controller. The factories helped in assisting the testing.&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/7ae2684a72dfd34706f77f4da62cf3bea06dab92 Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/e8d14390fbeedbc0748a695c121b787b53867727 Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/28e5212bec820b9e92b449d0b84edee77bbbdf79 Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/a82bf077613077eb89d5a6ce0c7adc903d93c674 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/385ab059443b9599d0abb4474d01b830116cb06f Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/7e8c53109d09f7dc4ce5d8074f56cfbc64614ba1 Commit Link 6]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158020</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158020"/>
		<updated>2024-10-30T01:17:47Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===[https://github.com/expertiza/reimplementation-back-end/pull/123/files Link to Pull Request]===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents.&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor '''grade_controller.rb''', which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment, and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
===Previous Iterations===&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's POV, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's POV which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's POV&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
! Relevant commit(s)&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/da9ec47222ba52f1ff675723a4d4fa051b4393e6 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/f9c353fad8e62e556398b0ec6905348ae7c35d36 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/1dcb5a1d124c1319757e8cea7c02c6a6d19e7cf7 Commit Link 2]&lt;br /&gt;
|-&lt;br /&gt;
|Created test files and factories to test our grades controller reimplementation.&lt;br /&gt;
|We needed to test the API endpoints for the grades controller. The factories helped in assisting the testing.&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/7ae2684a72dfd34706f77f4da62cf3bea06dab92 Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/e8d14390fbeedbc0748a695c121b787b53867727 Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/28e5212bec820b9e92b449d0b84edee77bbbdf79 Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/a82bf077613077eb89d5a6ce0c7adc903d93c674 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/385ab059443b9599d0abb4474d01b830116cb06f Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/7e8c53109d09f7dc4ce5d8074f56cfbc64614ba1 Commit Link 6]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Future Scope==&lt;br /&gt;
===Testing===&lt;br /&gt;
* '''Testing with rswag:'''&lt;br /&gt;
** Thoroughly test every controller method using '''rswag''' to generate documentation and ensure the controller operates as expected.&lt;br /&gt;
** Create and document test cases that verify the correct behavior of each method, particularly for edge cases and error scenarios.&lt;br /&gt;
* '''Swagger UI Video Documentation:'''&lt;br /&gt;
** Utilize '''Swagger UI''' to display the API endpoints, demonstrating how each controller method functions.&lt;br /&gt;
** Record a '''video walkthrough''' showcasing the Swagger UI for the reimplemented grades controller, providing a clear understanding of how the API interacts with the controller.&lt;br /&gt;
===Additional Features===&lt;br /&gt;
* Future renditions of this project could include additional functionality for varying charts and tables the frontend can utilize for displaying grades in a more helpful manner.&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158014</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=158014"/>
		<updated>2024-10-30T01:14:28Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents.&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor '''grade_controller.rb''', which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment, and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
===Previous Iterations===&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's POV, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's POV which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's POV&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
! Relevant commit(s)&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/da9ec47222ba52f1ff675723a4d4fa051b4393e6 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/f9c353fad8e62e556398b0ec6905348ae7c35d36 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Changed return types of all controller methods to render JSON Strings&lt;br /&gt;
|As Rails API methods the easiest and expected way to communicate with the new frontend is by rendering appropriate JSON response strings with HTTP status codes appended, this can allow the frontend to parse and handle returned data.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/c9bcab14340991847f574abfa8b13e641d476a1d Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/pull/123/commits/1dcb5a1d124c1319757e8cea7c02c6a6d19e7cf7 Commit Link 2]&lt;br /&gt;
|-&lt;br /&gt;
|Created test files and factories to test our grades controller reimplementation.&lt;br /&gt;
|We needed to test the API endpoints for the grades controller. The factories helped in assisting the testing.&lt;br /&gt;
|[https://github.com/expertiza/reimplementation-back-end/commit/7ae2684a72dfd34706f77f4da62cf3bea06dab92 Commit Link 1] [https://github.com/expertiza/reimplementation-back-end/commit/e8d14390fbeedbc0748a695c121b787b53867727 Commit Link 2] [https://github.com/expertiza/reimplementation-back-end/commit/28e5212bec820b9e92b449d0b84edee77bbbdf79 Commit Link 3] [https://github.com/expertiza/reimplementation-back-end/commit/a82bf077613077eb89d5a6ce0c7adc903d93c674 Commit Link 4] [https://github.com/expertiza/reimplementation-back-end/commit/385ab059443b9599d0abb4474d01b830116cb06f Commit Link 5] [https://github.com/expertiza/reimplementation-back-end/commit/7e8c53109d09f7dc4ce5d8074f56cfbc64614ba1 Commit Link 6]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Future Scope==&lt;br /&gt;
===Testing===&lt;br /&gt;
* '''Testing with rswag:'''&lt;br /&gt;
** Thoroughly test every controller method using '''rswag''' to generate documentation and ensure the controller operates as expected.&lt;br /&gt;
** Create and document test cases that verify the correct behavior of each method, particularly for edge cases and error scenarios.&lt;br /&gt;
* '''Swagger UI Video Documentation:'''&lt;br /&gt;
** Utilize '''Swagger UI''' to display the API endpoints, demonstrating how each controller method functions.&lt;br /&gt;
** Record a '''video walkthrough''' showcasing the Swagger UI for the reimplemented grades controller, providing a clear understanding of how the API interacts with the controller.&lt;br /&gt;
===Additional Features===&lt;br /&gt;
* Future renditions of this project could include additional functionality for varying charts and tables the frontend can utilize for displaying grades in a more helpful manner.&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=157983</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=157983"/>
		<updated>2024-10-30T00:56:57Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents.&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor '''grade_controller.rb''', which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment, and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
===Previous Iterations===&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's POV, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's POV which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's POV&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Change&lt;br /&gt;
! Rationale&lt;br /&gt;
! Relevant commit(s)&lt;br /&gt;
|-&lt;br /&gt;
| Refactored '''`action_allowed?`''' into '''`action_allowed`''', and added new helper methods&lt;br /&gt;
| The '''`grades#action_allowed?`''' method was not being called anywhere in the backend, which means this functionality is only presently used by the frontend. As such, '''`action_allowed?`''' needed to become a Rails API method and endpoint, meaning that it no longer returned a boolean (which is why it was renamed). Now it is a GET request to the appropriate route.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/da9ec47222ba52f1ff675723a4d4fa051b4393e6 Commit Link]&lt;br /&gt;
|-&lt;br /&gt;
|Added '''`participant_scores`''' model&lt;br /&gt;
|Added a participant scores model to belong to an assignment, '''`assignment_participant`''' and '''`question`'''. A participant score also holds a '''`score`''', '''`total_score`''' and '''`round`'''.&lt;br /&gt;
| [https://github.com/expertiza/reimplementation-back-end/commit/f9c353fad8e62e556398b0ec6905348ae7c35d36 Commit Link]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Future Scope==&lt;br /&gt;
===Testing===&lt;br /&gt;
* '''Testing with rswag:'''&lt;br /&gt;
** Thoroughly test every controller method using '''rswag''' to generate documentation and ensure the controller operates as expected.&lt;br /&gt;
** Create and document test cases that verify the correct behavior of each method, particularly for edge cases and error scenarios.&lt;br /&gt;
* '''Swagger UI Video Documentation:'''&lt;br /&gt;
** Utilize '''Swagger UI''' to display the API endpoints, demonstrating how each controller method functions.&lt;br /&gt;
** Record a '''video walkthrough''' showcasing the Swagger UI for the reimplemented grades controller, providing a clear understanding of how the API interacts with the controller.&lt;br /&gt;
===Additional Features===&lt;br /&gt;
* Future renditions of this project could include additional functionality for varying charts and tables the frontend can utilize for displaying grades in a more helpful manner.&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=157954</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=157954"/>
		<updated>2024-10-30T00:38:36Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents.&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor '''grade_controller.rb''', which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment, and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
===Previous Iterations===&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2024_-_E2443_Reimplement_grades_controller Spring 2024]&lt;br /&gt;
** This iteration was not approved to be pulled into expertiza, but provided our team with additional insight on how to more appropriately refactor the grades controller.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2107._Refactor_grades_controller.rb Spring 2021]&lt;br /&gt;
** Added additional methodology for providing model data, along with a greater focus on helper classes.&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2017/E1764_Refactor_Grades_Controller.rb Fall 2017]&lt;br /&gt;
** Refactored penalties, review systems, and utilized rspec testing.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's POV, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's POV which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's POV&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
==Future Scope==&lt;br /&gt;
===Testing===&lt;br /&gt;
* '''Testing with rswag:'''&lt;br /&gt;
** Thoroughly test every controller method using '''rswag''' to generate documentation and ensure the controller operates as expected.&lt;br /&gt;
** Create and document test cases that verify the correct behavior of each method, particularly for edge cases and error scenarios.&lt;br /&gt;
* '''Swagger UI Video Documentation:'''&lt;br /&gt;
** Utilize '''Swagger UI''' to display the API endpoints, demonstrating how each controller method functions.&lt;br /&gt;
** Record a '''video walkthrough''' showcasing the Swagger UI for the reimplemented grades controller, providing a clear understanding of how the API interacts with the controller.&lt;br /&gt;
===Additional Features===&lt;br /&gt;
* Future renditions of this project could include additional functionality for varying charts and tables the frontend can utilize for displaying grades in a more helpful manner.&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=157341</id>
		<title>CSC/ECE 517 Fall 2024 - E2470. Reimplement grades controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2470._Reimplement_grades_controller&amp;diff=157341"/>
		<updated>2024-10-29T00:58:21Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: Created page with &amp;quot;=E2470. Reimplement grades controller=  This page provides a description of the Expertiza based OSS project.    __TOC__   ===About Expertiza=== [http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instru...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2470. Reimplement grades controller=&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project utilizing the [http://rubyonrails.org/ Ruby on Rails] framework. It is meant to serve as an environment for classes to host assignments, teams, and evaluations of submissions. It is designed to provide instructors the ability to create and modify assignments. Instructors have access to viewing all completed assignments and grades given as well. Additionally, it allows the instructor to provide topic lists that students can access to determine which projects they sign up for. Students are able to form teams for projects and assignments, and during each they can review both peers and other submissions from teams. Expertiza is designed to support submission types ranging from URLs to varying documents.&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
The purpose of this project is to refactor '''grade_controller.rb''', which is responsible for all grading functionality within Expertiza. Its main purpose is to enable instructors to view all grades for an assignment, and allow students to view their own grades. Our main focus is to streamline functionality, remove redundancies, and provide more clarity to this refactored class.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks have been completed in this assignment:&lt;br /&gt;
&lt;br /&gt;
* '''Controller Refactoring''':&lt;br /&gt;
** Reimplement the existing '''grades_controller.rb''' to make it more modular, reusable, and compliant with the '''DRY''' (Don’t Repeat Yourself) principle.&lt;br /&gt;
** Improve the '''readability and maintainability''' of the codebase, ensuring it is easily understandable for future developers.&lt;br /&gt;
** Refactor code to eliminate unnecessary repetition and reduce complexity by adhering to '''SOLID''' design principles.&lt;br /&gt;
* '''CRUD Operations''':&lt;br /&gt;
** Ensure that the required '''CRUD operations''' (Read, Update) are properly implemented and optimized.&lt;br /&gt;
** Update methods to reflect best practices and consistent error handling mechanisms.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementation===&lt;br /&gt;
* One of the first major concerns we noticed was the reliance on an excessive amount of helper classes. Helper classes were being defined and provided to the '''grades_controller''', but no other class actually used them. It could be more consistent to keep that functionality stored within helper methods local to the class.&lt;br /&gt;
* Functions such as view/view_my_scores/view_team would contain calculations and functionality beyond the purpose of the method, which should be delegated to private methods to preserve modularity.&lt;br /&gt;
* The class contained obsolete variables in multiple methods which could be cleaned up.&lt;br /&gt;
* Chart methodology is contained within the backend which can now be delegated to the front end, since the controller should only be responsible for grading functionality and returning appropriate data. Model data should be provided to the front end.&lt;br /&gt;
* Penalty calculations are currently no longer relevant for the grading controller.&lt;br /&gt;
* There are currently no render statements for appropriately providing data to the front end.&lt;br /&gt;
&lt;br /&gt;
==Our Implementation==&lt;br /&gt;
&lt;br /&gt;
===Our Goals===&lt;br /&gt;
* Simplify the code structure in order to enhance readability by taking complex operations and unneeded local variable assignments into private helper methods within the grades_controller.  &lt;br /&gt;
* Enforce the intended functionality of the grades_controller by removing unneeded functionality and clutter, some of which is the responsibility of other controllers (i.e. calculating scores and penalties) or the frontend (i.e. rendering the bar chart information).  The functionalities of the grades_controller are as follows:&lt;br /&gt;
** Verify the user to ensure they are permitted to view the particular page they are looking for with the action_allowed controller method&lt;br /&gt;
** Provide needed information for the grade heatmap from the instructor's POV, with no hidden information such as reviewers id’s or names&lt;br /&gt;
** Provide needed information for the grade heatmap from the student's POV which obscures information such as the reviewer name/id&lt;br /&gt;
** Update the student's grade and make comments on it from the instructor's POV&lt;br /&gt;
* Cut down on repeated code to adhere to the DRY principle in order to improve maintainability and consistency within the code.&lt;br /&gt;
* Update the return values of the grades_controller methods in order to provide needed information and HTTP response codes that consistently reflect state and errors, as well as provide the required information for frontend tasks such as making the heatmap itself.&lt;br /&gt;
&lt;br /&gt;
===Routes and Methods===&lt;br /&gt;
* '''GET /api/v1/grades/action_allowed – action_allowed'''&lt;br /&gt;
** Checks if the current user is allowed to view scores or team information based on the queried action. Through helpers it focuses on checking if a student is viewing their own team’s scores, or if it’s an instructor trying to access grades. It renders a JSON response with status codes based on resulting output.&lt;br /&gt;
* '''GET /api/v1/grades/view/:id – view'''&lt;br /&gt;
** Prepares and provides data required for rendering a heat map for an instructor’s point of view. The helper method gathers all the relevant data before providing it in a JSON response with the scores, assignment details, average scores, and review score count.&lt;br /&gt;
* '''GET /api/v1/grades/view_team/:id – view_team'''&lt;br /&gt;
** Serves a similar function as the view statement, but focusing purely on the student’s perspective of their team. It provides data for rendering a heat map, but hides any sensitive information pertaining to grading, while also acquiring questions from the assignment. It renders a JSON response containing scores, assignment details, average scores, review score count, and questions.&lt;br /&gt;
* '''GET /api/v1/grades/edit/:id – edit'''&lt;br /&gt;
** Represents functionality for editing grade information, setting the scores for every question after listing the questions out. Renders a JSON  response with details about the participant, questions, scores, and assignment.&lt;br /&gt;
* '''GET /api/v1/grades/instructor_review/:id – instructor_review'''&lt;br /&gt;
** Provides the instructor with a rendered JSON response on whether there’s a new record or preexisting instance of a review.&lt;br /&gt;
* '''PATCH /api/v1/grades/update/:participant_id – update'''&lt;br /&gt;
** Updates the total score and comments for a team submission based on the received data. It finds the specified assignment, modifies the grade, and makes an attempt to save those changes. Upon failure it will provide an error message. &lt;br /&gt;
&lt;br /&gt;
==Future Scope==&lt;br /&gt;
===Testing===&lt;br /&gt;
* '''Testing with rswag:'''&lt;br /&gt;
** Thoroughly test every controller method using '''rswag''' to generate documentation and ensure the controller operates as expected.&lt;br /&gt;
** Create and document test cases that verify the correct behavior of each method, particularly for edge cases and error scenarios.&lt;br /&gt;
* '''Swagger UI Video Documentation:'''&lt;br /&gt;
** Utilize '''Swagger UI''' to display the API endpoints, demonstrating how each controller method functions.&lt;br /&gt;
** Record a '''video walkthrough''' showcasing the Swagger UI for the reimplemented grades controller, providing a clear understanding of how the API interacts with the controller.&lt;br /&gt;
===Additional Features===&lt;br /&gt;
* Future renditions of this project could include additional functionality for varying charts and tables the frontend can utilize for displaying grades in a more helpful manner.&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Srusti, Chaitanya&lt;br /&gt;
===Members===&lt;br /&gt;
* Eastin, Charlie&lt;br /&gt;
* Hulse, Jeremy&lt;br /&gt;
* Middleton, Maverick&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024&amp;diff=157333</id>
		<title>CSC/ECE 517 Fall 2024</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024&amp;diff=157333"/>
		<updated>2024-10-28T23:53:28Z</updated>

		<summary type="html">&lt;p&gt;Mtmiddle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[CSC/ECE 517 Fall 2024 - E2454. Refactor student_task.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2456. Refactor teams_user.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2459. View for results of bidding]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2461. UI for Courses]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2465. UI for Institutions and Notification]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2466. UI for Impersonate User]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2467. UI for View Submissions]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2469. Reimplement grades/view_team]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2470. Reimplement grades_controller]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2480. Implement testing for new Bookmarks Controller]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2482. Reimplement heatgrid for reviews]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2460 Mentor-Meeting Management]]&lt;/div&gt;</summary>
		<author><name>Mtmiddle</name></author>
	</entry>
</feed>