CSC/ECE 517 Spring 2022 - E2240. Re-write waitlist functionality

From Expertiza_Wiki
Jump to navigation Jump to search

Problem Statement

Waitlist feature is utilized during subject assignment in an assignment. For example, during the topic allocation of the Final Project (and design doc), each team had the opportunity to sign up for a topic in which they were interested or to add to a waitlist of a topic in which they were not interested. When a team is added to the queue, many circumstances emerge. The waitlist feature currently does not adhere to the open-closed design paradigm. As a result, our task in this project is to resolve these issues by rewriting the waitlist functionality.

Whenever a team requests for a topic, there are two things that can happen.

  • The topic is available: In this case, the team will be assigned this topic ( Assuming that there is no bidding for the assignment ). This is pretty straightforward.
  • The topic is unavailable: In this case, the team is waitlisted for the topic. When any other team drops this topic, a waitlisted team will be assigned for this topic.

We simplified the way we are handling the second case. For each topic, we have a waitlist object associated with it. If a team has requested for a topic that is not available, the team is queued on to the waitlist for this topic. In the waitlist table, we maintain the team id and the topic id for which this team is waitlisted. In the previous implementation, the waitlisting functionality is scattered across multiple files. All this is consolidated and placed in one model file ( waitlists.rb )

Issues with previous functionality

The previous implementation had multiple models and controllers ( sign_up_topic.rb, waitlist.rb, invitation.rb, lottery_controller.rb, suggestion_controller.rb and signed_up_team.rb etc ) perform actions that indirectly affect the waitlist ( adding or removing teams from waitlist ). As a result, modifying the waitlist is being performed by multiple models and controllers. So, there is a lot of redundancy associated with basic waitlist operations in multiple files.

Solution

To simplify waitlist functionality, to reduce code redundancy and to fix the Single-responsibility principle that is being violated, we have rewritten the methods in multiple controllers and model files that manipulate waitlists of a topic. All these classes now just invoke methods of waitlist_teams.rb. The following files contains the waitlist functionality which we have modified to refer to the new model file.

1) signed_up_team.rb

2) waitlist.rb

3) sign_up_sheet_controller.rb

4) sign_up_sheet.rb

5) sign_up_topic.rb

6) suggestion_controller.rb

7) invitation.rb

Design

Achieved Design Goals

Since our goal is to fix existing functionalities we did not update the existing design patterns being employed in the code. Yet, we would like to discuss what makes these refactoring important. Refactoring is a systematic process of improving code without creating new functionality. Thus, a key to the success of our project is ensuring everything that was working before our changes work even after our changes have been added.
We have eliminated the waitlist.rb file and moved all the references to this class to the new waitlist_teams.rb model file. We tested the existing features and ensured that we are not breaking what was working before we deployed our fix. We can say that we achieved our goal of making experiza system more reliable and have code that is consistent with the standards of object-oriented design.

UML Diagram

In this Unified Modeling Language (UML), we summarize the details of the system's users and their interactions with the system.
We have two users to the system Student and Instructor. The interactions these users have with the system are stated below.


Student Interactions
1. Student should be able to perform an action to add their own team to the waitlist.
2. Student should be able to drop their own team from the waitlist but not others team.

Instructor Interactions
1. Delete or purge on the waitlist items are those actions that have to be performed by the instructor/admin and student should not be given access to delete action.
2. Instructor should be able to add any team to the waitlist.
3. Instructor should be able to drop any team from the waitlist.
4. Instructor should be able to fetch the details of the teams in a waitlist for a particular topic.
5. Instructor should be able to fetch the details of the topics in which a team is waitlisted.


Class Diagram

Tables associated with waitlist_teams table are
1. teams
2. signed_up_teams

waitlist_teams table is referred by the signed_up_teams and teams table as Foreign Key Relationship.

team_id : foreign key in waitlists_team table which is a reference to the teams table
topic_id : foreign key in waitlists_team table which is a reference to the signed_up_teams table

These relationships along with the attributes of the classes are depicted in the class diagram below.

Actions performed

Following are the sections of changes that we have done in this project :
1. Updated the SIGNED_UP_TEAMS table.
2. Refactored files that contains waitlist functionality
3. Added new WAITLIST_TEAMS table using scaffold.
4. Migrated the data to WAITLIST_TEAMS table from SIGNED_UP_TEAMS table.
5. Added the business logic to waitlist_teams.rb file

1.Changes done to the signed_up_teams Table

signed_up_teams table consists of a mapping of team_id, topic_id, is_waitlisted. This table was being used for multiple purposes, one to store the signed up teams and also the waitlisted teams for a topic.
We have eliminated the use of is_waitlisted column of this table. Instead, we have used a separate table waitlist_teams for waitlisting entries. With this, the signed_up_teams table consists of only signed up teams and waitlist_teams consists of only waitlisted up teams.
All existing references to the is_waitlisted flag has been rewritten to make use of the new table.

2. Files and methods refactored

  1. signed_up_team.rb
    1. All references to the is_waitlisted boolean flag are removed and waitlists are determined by using the new waitlist_team table.
  2. waitlist.rb
    1. We have completely eliminated this class. We have used WaitlistTeam in place of this class and this contains all business logic for managing waitlisted teams for topics.
      Refer to this commit to view the changes.
  3. sign_up_sheet_controller.rb
    1. set_values_for_new_topic
      1. Added code to get waitlisted entries from new table instead of having all the entries from signed_up_teams table.
        Refer to this commit to view the changes.
  4. sign_up_sheet.rb
    1. cancel_all_wailists
      1. This method previously has done 2 things, it cancelled waitlist and also updated the signed_up_team topic which needs to be split to comply with single responsibility principle. We ensured that is happening in the current implementation.
        Refer to this commit to view the changes.
    2. create_SignUpTeam
      1. This method in the previous implementation checked if topic has slots. If yes, it added to signed up team, else created a signup as waitlist.
        We modified this in order to use the new table and call the functions of waitlist_teams.rb to perform actions on waitlists.
        Refer to this commit to view the changes.
  5. sign_up_topic.rb
    1. users_on_waiting_list - Moved this method to fetch all users on waitlist for a topic to waitlist_teams model file.
    2. assign_to_first_waiting_team - The same functionality is being called in multiple places. This is modified to comply with DRY and is moved to the waitlist_teams model
    3. reassign_topic - Modified this method to use waitlist_teams.rb model file for actions on waitlisted teams.
    4. update_waitlisted_users - Moved this method to waitlist_teams model file.
    5. find_slots_waitlisted - Moved this method to waitlist_teams model file.
    6. find_waitlisted_topics - Moved this method to waitlist_teams model file.
      Refer to this diff to view the changes.
  6. suggestion_controller.rb
    1. notification - Clean waitlist functionality is moved to a method in waitlist_teams model. team id is passed as a parameter to delete the waitlist for that team.
      Refer to this PR to view the changes.
  7. invitation.rb
    1. remove_waitlists_for_team - Removed this method as we dont need it in this file.
      Refer to this diff to view the changes.

3. Added new waitlist_teams Table

We added a new table waitlist_teams
The attributes for the table are team_id(refers to the teams table), topic_id (refers to the sign_up_topics table)
This table only stores the waitlisted teams for each topic.
The default timestamp in the table is used to check the first team waitlisted instead of using queues to implement the functionality.
Having separated tables for signups and waitlists helps us in managing entries and enforcing constraints and makes it easier to implement and extend functionality if required.

The waitlist_teams.rb model class performs the following operations

  1. Delete all waitlists for team
  2. Purge all waitlists for topic
  3. Add team to waitlist
  4. Delete specific team from waitlist
  5. Get all waitlisted topics for team
  6. Get all waitlisted teams for topic
  7. Get first team in waitlist for topic
  8. Check waitlist empty for topic
  9. Check if team has any waitlists
  10. Get the number of waitlisted teams for all topics in an assignment.
    Refer to this file to view the waitlist_teams model.

4. Migrated existing waitlists to use new table

Since the signed_up_teams table will no longer be used to store the waitlists, we moved all the entries for waitlisted teams to the new table so that all the existing waitlists don't get affected.
We have written a migration script to move the waitlists from signed_up_teams table to waitlist_teams table.
This ensures minimal regression breakages and that all existing functionalities are retained.
Refer to this file to view the migration script.

Implementation

1. Waitlist Teams Table, Validations and Model file:
https://github.com/akhilkumarmengani/expertiza/pull/1/files (Adding waitlist_teams table)
https://github.com/akhilkumarmengani/expertiza/pull/2/files (Migration script changes to add unique constraint on waitlist_teams table and remove id column)
https://github.com/akhilkumarmengani/expertiza/pull/4/files (Schema changes)
https://github.com/akhilkumarmengani/expertiza/pull/3/files (Validations)

2. Migration Scripts
https://github.com/akhilkumarmengani/expertiza/pull/10/files (Migrate existing data in signed_up_teams to waitlist_teams)

3. Business Logic Changes
Adding new methods for add, delete, signup of waitlist teams in WaitlistTeam.rb.
Changes to existing method calls in model files

https://github.com/akhilkumarmengani/expertiza/pull/5/files (WaitlistTeam model methods like CRUD etc)
https://github.com/akhilkumarmengani/expertiza/pull/11/files (Methods to handle deletion cases)
https://github.com/akhilkumarmengani/expertiza/pull/12 (Check if team is waitlisted before a topic signup)
https://github.com/akhilkumarmengani/expertiza/pull/13 (Release waitlist and signup when a user joins another team and there are no other users in the old team)
https://github.com/akhilkumarmengani/expertiza/pull/14/files (Synchronize waitlist features in other files)

4. RSpec
https://github.com/akhilkumarmengani/expertiza/pull/13 (RSpec changes to test model methods)

Testing

Video Demonstration

Please watch this Video Demonstration where we explain the bugs we rectified in this project.

Testing Goals and Test Objects

Drawing from the project objectives:

  1. Ways to get added to the waitlist for a topic
    1. Team requests a topic that has no slot available.
    2. When capacity/max choosers for a topic is increased
    3. When a student gets added to a team that already has a signed up topic
  2. Ways to get off a waitlist
    1. team gets the topic they are waiting for ( all other waitlists are dropped for the team)
    2. team drops off the waitlist
    3. instructor drops team from the waitlist
    4. a drop-topic deadline passes
    5. team is deleted
    6. student gets added to a new team, then the old team's waitlist should be dropped


RSpec Unit Tests

  • Student Waitlist
    • Refer to this diff to view the RSpec unit tests for waitlist_teams.rb model file. Few of them are
Scenario: Getting enrolled in a topic 
 Given: Logged in as a Student
  When: The topic for an assignment has available slots
   And: Student tries to signup for a topic
  Then: The team that the student is a part of should be enrolled for the topic.
Scenario: Getting added to the waitlist for a topic 
 Given: Logged in as a Student
  When: The topic for an assignment has no available slots
   And: Student tries to signup for a topic
  Then: The team that the student is a part of should be added to the waitlist for the topic.
Scenario: Drop team from the waitlist for a topic 
 Given: Logged in as a Student
  When: The student is waitlisted for a topic
   And: Student drops from the waitlist of this topic
  Then: The team that the student is a part of should be dropped from the waitlist for the topic.
Scenario: Getting enrolled in a topic
 Given: Logged in as a Student
  When: The enrolled team for a topic drops
  Then: The team that was waitlisted earlier for the topics must be enrolled.
Scenario: All waitlisted topics getting dropped
 Given: Logged in as a Student
  When: Student gets enrolled into a course for which he was waitlisted before.
  Then: The team that the student is a part of should be dropped from the remaining waitlisted topics.
Scenario: All waitlisted teams getting dropped
 Given: Logged in as a Student
  When: The deadline for a topic passes.
  Then: All the waitlisted teams for that particular topic must be dropped.

Regression Testing

In order to ensure complete coverage, testing of the changes done between the end of last semester and this project is done to ensure that old test cases still pass.
Refer to this PR to view the changes to old test cases.

Manual Testing

Student's View




Instructor's View



Instructor's View With Waitlists




Test 1:
Student should be able to add their team to the waitlist by clicking on Check icon (see the image above) if the team has not signed up in any topic.

Test 2:
Student should be able to drop the team from the waitlist by clicking on Delete icon (see the image above) if they are no longer interested in it.

Test 3:
Instructor should be able to add a student to the topic by clicking on Check (see the image above) icon.

Test 4:
Instructor should be able to delete a student to the topic by clicking on Delete (see the image above) icon.

Test 5:
Instructor should be able to view all the students signup for a topic in the page displayed.

Test 6:
Instructor should be able to view all the topics available

Test 7:
Instructor should be able to view waitlisted and signed up teams for all the topics in the assignment

Test 8:
Instructor should be able to drop waitlisted team for a topics in the assignment.

Conclusions and Future Work

Conclusion:
Following is the summary of what we have done in this project so far:
1. Adding new table waitlist_teams to store waitlist teams for a topic and migration script for transferring the waitlist data from signed_up_teams.
2. Changed the existing functionality to store the new waitlists data in this new table
3. Existing waitlist business logic implementation is not in waitlist model class so we created a new model file and rewritten the code for waitlist functionality.
4. There are number of methods in other model classes which are referencing waitlist functionality. We have changed all those references to the new methods that we have implemented.

Future Work:
1. We created a new table that will store the team in waitlist for a topic. Earlier there was only table (signed_up_teams) to keep track of signed up teams and waitlist teams. This table has is_waitlist column to figure out if the entry is for a sign up or waitlist. With the Introduction of new table for waitlist_teams this column now seems unreasonable and it will not impact the functionality. Though we have script to migrate the existing waitlist data to new table, the column is_waitlist is not removed yet. Teams working on it further can work on it and remove all the references of is_waitlist column.
2. Teams can work on writing more test cases for waitlist functionality because there are various flows in which this functionality is touched Examples: Accept Invitation, Leaving team etc.

Useful Links

Pull request

Deployed application with changes

Forked repository

Contributors

Students

  • Krishna Saurabh Vankadaru (kvankad)
  • Samson Reddy Mulkur (smulkur)
  • Akhil Kumar Mengani (amengan)
  • Sai Naga Vamshi Chidara (schidar)

Mentor

  • Naman Shrimali (nshrima)