<?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=Akilled</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=Akilled"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Akilled"/>
	<updated>2026-06-30T00:49:32Z</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_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160814</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160814"/>
		<updated>2024-12-04T16:17:25Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* Schema */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:NewSchema.png| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML Notif.png | center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== New Files ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Model for Notification (models/notification.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/models/notification.rb Commit]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class Notification &amp;lt; ApplicationRecord&lt;br /&gt;
  # Associations&lt;br /&gt;
  belongs_to :course, foreign_key: :course_name, primary_key: :name&lt;br /&gt;
  belongs_to :user&lt;br /&gt;
  # Validations&lt;br /&gt;
  validates :subject, presence: true, length: { maximum: 255 }&lt;br /&gt;
  validates :description, presence: true&lt;br /&gt;
  validates :expiration_date, presence: true&lt;br /&gt;
  validate :expiration_date_cannot_be_in_the_past&lt;br /&gt;
  # Scopes&lt;br /&gt;
  scope :active, -&amp;gt; { where(active_flag: true) }&lt;br /&gt;
  scope :expired, -&amp;gt; { where('expiration_date &amp;lt; ?', Date.today) }&lt;br /&gt;
  scope :unread_by, -&amp;gt;(user) {&lt;br /&gt;
    joins(:course).where(courses: { id: user.assignments.pluck(:course_id) }).where(active_flag: true)&lt;br /&gt;
  }&lt;br /&gt;
  # Custom Validation for Expiration Date&lt;br /&gt;
  def expiration_date_cannot_be_in_the_past&lt;br /&gt;
    if expiration_date.present? &amp;amp;&amp;amp; expiration_date &amp;lt; Date.today&lt;br /&gt;
      errors.add(:expiration_date, &amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; 2. Controller for Notification (controllers/notification_controller.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/controllers/api/v1/notifications_controller.rb Commit]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class Api::V1::NotificationsController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
  before_action :set_notification, only: %i[show update destroy]&lt;br /&gt;
  # GET /notifications&lt;br /&gt;
  def index&lt;br /&gt;
    if current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      @notifications = Notification.where(user_id: current_user.id)&lt;br /&gt;
    elsif current_user_has_student_privileges?&lt;br /&gt;
      course_names = current_user.courses.pluck(:name)&lt;br /&gt;
      @notifications = Notification.where(course_name: course_names, active_flag: true)&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Access denied' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: @notifications&lt;br /&gt;
  end&lt;br /&gt;
  # GET /notifications/:id&lt;br /&gt;
  def show&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      render json: @notification&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You do not have access to this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # POST /notifications&lt;br /&gt;
  def create&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to create notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end &lt;br /&gt;
    @notification = Notification.new(notification_params)&lt;br /&gt;
    @notification.user_id = current_user.id&lt;br /&gt;
  &lt;br /&gt;
    if @notification.save&lt;br /&gt;
      render json: @notification, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH/PUT /notifications/:id&lt;br /&gt;
  def update&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to update notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.update(notification_params)&lt;br /&gt;
      render json: @notification, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # DELETE /notifications/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to delete notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.destroy&lt;br /&gt;
      render json: { message: 'Notification deleted successfully.' }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Failed to delete the notification.' }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH /notifications/:id/toggle_active&lt;br /&gt;
  def toggle_notification_visibility&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      @notification.update(active_flag: !@notification.active_flag)&lt;br /&gt;
      render json: { message: 'Notification visibility toggled successfully.', notification: @notification }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You are not authorized to toggle this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_notification&lt;br /&gt;
    @notification = Notification.find(params[:id])&lt;br /&gt;
  rescue ActiveRecord::RecordNotFound&lt;br /&gt;
    render json: { error: 'Notification not found.' }, status: :not_found&lt;br /&gt;
  end&lt;br /&gt;
  # Define strong parameters for notification creation/update&lt;br /&gt;
  def notification_params&lt;br /&gt;
    params.require(:notification).permit(:course_name, :subject, :description, :expiration_date, :active_flag)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method to check if a notification is accessible to the current user&lt;br /&gt;
  def notification_accessible?(notification)&lt;br /&gt;
    # Instructors and TAs can access their own notifications&lt;br /&gt;
    return true if notification.user_id == current_user.id&lt;br /&gt;
    # Students can access notifications for their courses&lt;br /&gt;
    return true if current_user_has_student_privileges? &amp;amp;&amp;amp;&lt;br /&gt;
                   current_user.courses.exists?(name: notification.course_name)&lt;br /&gt;
    false&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Patterns and SOLID principles uses=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Following are the some of the SOLID principles with how they will be applied to the back-end development:&amp;lt;/b&amp;gt;&lt;br /&gt;
* Single Responsibility : Controllers handle HTTP requests, models handle data, and service objects handle business logic (e.g., sending notifications).&lt;br /&gt;
* Open/Closed : Extend functionality (e.g., new notification types or filters) by adding new classes or methods without modifying existing code.&lt;br /&gt;
* Interface Segregation : Create small, role-specific interfaces (e.g., policies for TAs, students, instructors) and separate service objects for different types of notifications.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
This section outlines the comprehensive testing approach for the Notifications feature to ensure it meets functional and non-functional requirements. The strategy includes detailed test cases for models, controllers, role-based access, and error handling, leveraging RSpec for testing and RSwag for API documentation.&lt;br /&gt;
&lt;br /&gt;
'''1. Unit Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure that the Notification model functions as expected by validating its attributes, associations, and methods.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/spec/models/notification_spec.rb File as on GitHub]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
* Validations:&lt;br /&gt;
** Presence validation for subject, description, expiration_date, course_id, and user_id.&lt;br /&gt;
** Length constraints on subject and description.&lt;br /&gt;
** Format validation for expiration_date.&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :user and belongs_to :course associations are correctly established.&lt;br /&gt;
** Notifications have appropriate relationships with Course and User models.&lt;br /&gt;
&lt;br /&gt;
* Custom Methods and Scopes:&lt;br /&gt;
** active_notifications: Ensure only active notifications are returned.&lt;br /&gt;
** unread_notifications: Validate that unread notifications are fetched correctly.&lt;br /&gt;
&lt;br /&gt;
* Edge Cases:&lt;br /&gt;
** Notifications with an expired expiration_date should not appear in the active notifications list.&lt;br /&gt;
** Handling invalid foreign keys for user_id and course_id.&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe Notification, type: :model do&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it { should validate_presence_of(:subject) }&lt;br /&gt;
    it { should validate_presence_of(:description) }&lt;br /&gt;
    it { should validate_presence_of(:expiration_date) }&lt;br /&gt;
    it { should validate_length_of(:subject).is_at_most(100) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it { should belong_to(:user) }&lt;br /&gt;
    it { should belong_to(:course) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    let!(:active_notification) { create(:notification, is_active: true) }&lt;br /&gt;
    let!(:expired_notification) { create(:notification, expiration_date: Date.yesterday) }&lt;br /&gt;
    it 'returns active notifications' do&lt;br /&gt;
      expect(Notification.active_notifications).to include(active_notification)&lt;br /&gt;
      expect(Notification.active_notifications).not_to include(expired_notification)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Controller Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Test all CRUD operations for the Notifications controller to ensure endpoints function as expected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Index Action:&lt;br /&gt;
** Ensure all notifications for a given user are returned.&lt;br /&gt;
** Verify that unauthorized users cannot access the endpoint.&lt;br /&gt;
** Test paginated responses if applicable.&lt;br /&gt;
* Show Action:&lt;br /&gt;
** Ensure notifications can be retrieved by id.&lt;br /&gt;
** Handle cases where id is invalid or unauthorized.&lt;br /&gt;
* Create Action:&lt;br /&gt;
** Validate successful creation of notifications with proper attributes.&lt;br /&gt;
** Handle validation failures and unauthorized access.&lt;br /&gt;
* Update Action:&lt;br /&gt;
** Test updates to notification attributes.&lt;br /&gt;
** Ensure unauthorized users cannot perform updates.&lt;br /&gt;
* Delete Action:&lt;br /&gt;
** Verify notifications are deleted successfully.&lt;br /&gt;
** Test behavior when id is invalid or unauthorized.&lt;br /&gt;
&lt;br /&gt;
 require 'rails_helper'&lt;br /&gt;
 RSpec.describe Api::V1::NotificationsController, type: :controller do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let(:notification) { create(:notification) }&lt;br /&gt;
  describe 'GET #index' do&lt;br /&gt;
    before { sign_in admin }&lt;br /&gt;
    it 'returns notifications for the current user' do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:ok)&lt;br /&gt;
      expect(json_response).to include(notification)&lt;br /&gt;
    end&lt;br /&gt;
    it 'denies access to unauthorized users' do&lt;br /&gt;
      sign_out admin&lt;br /&gt;
      sign_in student&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:forbidden)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  describe 'POST #create' do&lt;br /&gt;
    context 'with valid attributes' do&lt;br /&gt;
      it 'creates a new notification' do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { notification: attributes_for(:notification) }&lt;br /&gt;
        }.to change(Notification, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'with invalid attributes' do&lt;br /&gt;
      it 'returns validation errors' do&lt;br /&gt;
        post :create, params: { notification: { subject: '' } }&lt;br /&gt;
        expect(response).to have_http_status(:unprocessable_entity)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''3. Integration Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure seamless interaction between models, controllers, and role-based access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Role-Based Access:&lt;br /&gt;
** Verify only authorized roles (e.g., Admin, Instructor) can manage notifications.&lt;br /&gt;
** Ensure students can only view notifications for their enrolled courses.&lt;br /&gt;
* Full CRUD Workflow:&lt;br /&gt;
** Test end-to-end creation, updating, and deletion of notifications.&lt;br /&gt;
* Error Scenarios:&lt;br /&gt;
** Handle cases where a notification is created for a non-existent course or user.&lt;br /&gt;
** Verify appropriate error messages for unauthorized actions.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications Integration', type: :request do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let!(:notification) { create(:notification, user: admin) }&lt;br /&gt;
  it 'allows admins to create notifications' do&lt;br /&gt;
    sign_in admin&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:created)&lt;br /&gt;
  end&lt;br /&gt;
  it 'prevents students from creating notifications' do&lt;br /&gt;
    sign_in student&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:forbidden)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''4. API Documentation and Testing with RSwag'''&lt;br /&gt;
&lt;br /&gt;
Goal: Generate API documentation and test all endpoints.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get 'Retrieve notifications' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      response '200', 'success' do&lt;br /&gt;
        schema type: :array, items: { type: :object, properties: { id: { type: :integer }, subject: { type: :string } } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    post 'Create a notification' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: 'date' },&lt;br /&gt;
          is_active: { type: :boolean }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject description expiration_date]&lt;br /&gt;
      }&lt;br /&gt;
      response '201', 'created' do&lt;br /&gt;
        let(:notification) { { subject: 'Test', description: 'Test notification', expiration_date: '2024-12-31', is_active: true } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;br /&gt;
* '''Demo Video Link''' [https://youtu.be/pct11aDPMRM?si=5HdZK3EGeW1z21Y_]&lt;br /&gt;
* '''Pull Request Link''' [https://github.com/expertiza/reimplementation-back-end/pull/142]&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:NewSchema.png&amp;diff=160813</id>
		<title>File:NewSchema.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:NewSchema.png&amp;diff=160813"/>
		<updated>2024-12-04T16:17:15Z</updated>

		<summary type="html">&lt;p&gt;Akilled: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Schema2.PNG&amp;diff=160812</id>
		<title>File:Schema2.PNG</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Schema2.PNG&amp;diff=160812"/>
		<updated>2024-12-04T16:15:51Z</updated>

		<summary type="html">&lt;p&gt;Akilled: Akilled uploaded a new version of File:Schema2.PNG&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160811</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160811"/>
		<updated>2024-12-04T16:12:11Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* UML Diagram */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML Notif.png | center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== New Files ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Model for Notification (models/notification.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/models/notification.rb Commit]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class Notification &amp;lt; ApplicationRecord&lt;br /&gt;
  # Associations&lt;br /&gt;
  belongs_to :course, foreign_key: :course_name, primary_key: :name&lt;br /&gt;
  belongs_to :user&lt;br /&gt;
  # Validations&lt;br /&gt;
  validates :subject, presence: true, length: { maximum: 255 }&lt;br /&gt;
  validates :description, presence: true&lt;br /&gt;
  validates :expiration_date, presence: true&lt;br /&gt;
  validate :expiration_date_cannot_be_in_the_past&lt;br /&gt;
  # Scopes&lt;br /&gt;
  scope :active, -&amp;gt; { where(active_flag: true) }&lt;br /&gt;
  scope :expired, -&amp;gt; { where('expiration_date &amp;lt; ?', Date.today) }&lt;br /&gt;
  scope :unread_by, -&amp;gt;(user) {&lt;br /&gt;
    joins(:course).where(courses: { id: user.assignments.pluck(:course_id) }).where(active_flag: true)&lt;br /&gt;
  }&lt;br /&gt;
  # Custom Validation for Expiration Date&lt;br /&gt;
  def expiration_date_cannot_be_in_the_past&lt;br /&gt;
    if expiration_date.present? &amp;amp;&amp;amp; expiration_date &amp;lt; Date.today&lt;br /&gt;
      errors.add(:expiration_date, &amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; 2. Controller for Notification (controllers/notification_controller.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/controllers/api/v1/notifications_controller.rb Commit]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class Api::V1::NotificationsController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
  before_action :set_notification, only: %i[show update destroy]&lt;br /&gt;
  # GET /notifications&lt;br /&gt;
  def index&lt;br /&gt;
    if current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      @notifications = Notification.where(user_id: current_user.id)&lt;br /&gt;
    elsif current_user_has_student_privileges?&lt;br /&gt;
      course_names = current_user.courses.pluck(:name)&lt;br /&gt;
      @notifications = Notification.where(course_name: course_names, active_flag: true)&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Access denied' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: @notifications&lt;br /&gt;
  end&lt;br /&gt;
  # GET /notifications/:id&lt;br /&gt;
  def show&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      render json: @notification&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You do not have access to this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # POST /notifications&lt;br /&gt;
  def create&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to create notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end &lt;br /&gt;
    @notification = Notification.new(notification_params)&lt;br /&gt;
    @notification.user_id = current_user.id&lt;br /&gt;
  &lt;br /&gt;
    if @notification.save&lt;br /&gt;
      render json: @notification, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH/PUT /notifications/:id&lt;br /&gt;
  def update&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to update notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.update(notification_params)&lt;br /&gt;
      render json: @notification, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # DELETE /notifications/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to delete notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.destroy&lt;br /&gt;
      render json: { message: 'Notification deleted successfully.' }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Failed to delete the notification.' }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH /notifications/:id/toggle_active&lt;br /&gt;
  def toggle_notification_visibility&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      @notification.update(active_flag: !@notification.active_flag)&lt;br /&gt;
      render json: { message: 'Notification visibility toggled successfully.', notification: @notification }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You are not authorized to toggle this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_notification&lt;br /&gt;
    @notification = Notification.find(params[:id])&lt;br /&gt;
  rescue ActiveRecord::RecordNotFound&lt;br /&gt;
    render json: { error: 'Notification not found.' }, status: :not_found&lt;br /&gt;
  end&lt;br /&gt;
  # Define strong parameters for notification creation/update&lt;br /&gt;
  def notification_params&lt;br /&gt;
    params.require(:notification).permit(:course_name, :subject, :description, :expiration_date, :active_flag)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method to check if a notification is accessible to the current user&lt;br /&gt;
  def notification_accessible?(notification)&lt;br /&gt;
    # Instructors and TAs can access their own notifications&lt;br /&gt;
    return true if notification.user_id == current_user.id&lt;br /&gt;
    # Students can access notifications for their courses&lt;br /&gt;
    return true if current_user_has_student_privileges? &amp;amp;&amp;amp;&lt;br /&gt;
                   current_user.courses.exists?(name: notification.course_name)&lt;br /&gt;
    false&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Patterns and SOLID principles uses=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Following are the some of the SOLID principles with how they will be applied to the back-end development:&amp;lt;/b&amp;gt;&lt;br /&gt;
* Single Responsibility : Controllers handle HTTP requests, models handle data, and service objects handle business logic (e.g., sending notifications).&lt;br /&gt;
* Open/Closed : Extend functionality (e.g., new notification types or filters) by adding new classes or methods without modifying existing code.&lt;br /&gt;
* Interface Segregation : Create small, role-specific interfaces (e.g., policies for TAs, students, instructors) and separate service objects for different types of notifications.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
This section outlines the comprehensive testing approach for the Notifications feature to ensure it meets functional and non-functional requirements. The strategy includes detailed test cases for models, controllers, role-based access, and error handling, leveraging RSpec for testing and RSwag for API documentation.&lt;br /&gt;
&lt;br /&gt;
'''1. Unit Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure that the Notification model functions as expected by validating its attributes, associations, and methods.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/spec/models/notification_spec.rb File as on GitHub]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
* Validations:&lt;br /&gt;
** Presence validation for subject, description, expiration_date, course_id, and user_id.&lt;br /&gt;
** Length constraints on subject and description.&lt;br /&gt;
** Format validation for expiration_date.&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :user and belongs_to :course associations are correctly established.&lt;br /&gt;
** Notifications have appropriate relationships with Course and User models.&lt;br /&gt;
&lt;br /&gt;
* Custom Methods and Scopes:&lt;br /&gt;
** active_notifications: Ensure only active notifications are returned.&lt;br /&gt;
** unread_notifications: Validate that unread notifications are fetched correctly.&lt;br /&gt;
&lt;br /&gt;
* Edge Cases:&lt;br /&gt;
** Notifications with an expired expiration_date should not appear in the active notifications list.&lt;br /&gt;
** Handling invalid foreign keys for user_id and course_id.&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe Notification, type: :model do&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it { should validate_presence_of(:subject) }&lt;br /&gt;
    it { should validate_presence_of(:description) }&lt;br /&gt;
    it { should validate_presence_of(:expiration_date) }&lt;br /&gt;
    it { should validate_length_of(:subject).is_at_most(100) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it { should belong_to(:user) }&lt;br /&gt;
    it { should belong_to(:course) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    let!(:active_notification) { create(:notification, is_active: true) }&lt;br /&gt;
    let!(:expired_notification) { create(:notification, expiration_date: Date.yesterday) }&lt;br /&gt;
    it 'returns active notifications' do&lt;br /&gt;
      expect(Notification.active_notifications).to include(active_notification)&lt;br /&gt;
      expect(Notification.active_notifications).not_to include(expired_notification)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Controller Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Test all CRUD operations for the Notifications controller to ensure endpoints function as expected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Index Action:&lt;br /&gt;
** Ensure all notifications for a given user are returned.&lt;br /&gt;
** Verify that unauthorized users cannot access the endpoint.&lt;br /&gt;
** Test paginated responses if applicable.&lt;br /&gt;
* Show Action:&lt;br /&gt;
** Ensure notifications can be retrieved by id.&lt;br /&gt;
** Handle cases where id is invalid or unauthorized.&lt;br /&gt;
* Create Action:&lt;br /&gt;
** Validate successful creation of notifications with proper attributes.&lt;br /&gt;
** Handle validation failures and unauthorized access.&lt;br /&gt;
* Update Action:&lt;br /&gt;
** Test updates to notification attributes.&lt;br /&gt;
** Ensure unauthorized users cannot perform updates.&lt;br /&gt;
* Delete Action:&lt;br /&gt;
** Verify notifications are deleted successfully.&lt;br /&gt;
** Test behavior when id is invalid or unauthorized.&lt;br /&gt;
&lt;br /&gt;
 require 'rails_helper'&lt;br /&gt;
 RSpec.describe Api::V1::NotificationsController, type: :controller do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let(:notification) { create(:notification) }&lt;br /&gt;
  describe 'GET #index' do&lt;br /&gt;
    before { sign_in admin }&lt;br /&gt;
    it 'returns notifications for the current user' do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:ok)&lt;br /&gt;
      expect(json_response).to include(notification)&lt;br /&gt;
    end&lt;br /&gt;
    it 'denies access to unauthorized users' do&lt;br /&gt;
      sign_out admin&lt;br /&gt;
      sign_in student&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:forbidden)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  describe 'POST #create' do&lt;br /&gt;
    context 'with valid attributes' do&lt;br /&gt;
      it 'creates a new notification' do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { notification: attributes_for(:notification) }&lt;br /&gt;
        }.to change(Notification, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'with invalid attributes' do&lt;br /&gt;
      it 'returns validation errors' do&lt;br /&gt;
        post :create, params: { notification: { subject: '' } }&lt;br /&gt;
        expect(response).to have_http_status(:unprocessable_entity)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''3. Integration Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure seamless interaction between models, controllers, and role-based access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Role-Based Access:&lt;br /&gt;
** Verify only authorized roles (e.g., Admin, Instructor) can manage notifications.&lt;br /&gt;
** Ensure students can only view notifications for their enrolled courses.&lt;br /&gt;
* Full CRUD Workflow:&lt;br /&gt;
** Test end-to-end creation, updating, and deletion of notifications.&lt;br /&gt;
* Error Scenarios:&lt;br /&gt;
** Handle cases where a notification is created for a non-existent course or user.&lt;br /&gt;
** Verify appropriate error messages for unauthorized actions.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications Integration', type: :request do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let!(:notification) { create(:notification, user: admin) }&lt;br /&gt;
  it 'allows admins to create notifications' do&lt;br /&gt;
    sign_in admin&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:created)&lt;br /&gt;
  end&lt;br /&gt;
  it 'prevents students from creating notifications' do&lt;br /&gt;
    sign_in student&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:forbidden)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''4. API Documentation and Testing with RSwag'''&lt;br /&gt;
&lt;br /&gt;
Goal: Generate API documentation and test all endpoints.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get 'Retrieve notifications' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      response '200', 'success' do&lt;br /&gt;
        schema type: :array, items: { type: :object, properties: { id: { type: :integer }, subject: { type: :string } } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    post 'Create a notification' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: 'date' },&lt;br /&gt;
          is_active: { type: :boolean }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject description expiration_date]&lt;br /&gt;
      }&lt;br /&gt;
      response '201', 'created' do&lt;br /&gt;
        let(:notification) { { subject: 'Test', description: 'Test notification', expiration_date: '2024-12-31', is_active: true } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;br /&gt;
* '''Demo Video Link''' [https://youtu.be/pct11aDPMRM?si=5HdZK3EGeW1z21Y_]&lt;br /&gt;
* '''Pull Request Link''' [https://github.com/expertiza/reimplementation-back-end/pull/142]&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:UML_Notif.png&amp;diff=160810</id>
		<title>File:UML Notif.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:UML_Notif.png&amp;diff=160810"/>
		<updated>2024-12-04T16:11:53Z</updated>

		<summary type="html">&lt;p&gt;Akilled: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160693</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160693"/>
		<updated>2024-12-04T04:58:37Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== New Files ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Model for Notification (models/notification.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/models/notification.rb Commit]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class Notification &amp;lt; ApplicationRecord&lt;br /&gt;
  # Associations&lt;br /&gt;
  belongs_to :course, foreign_key: :course_name, primary_key: :name&lt;br /&gt;
  belongs_to :user&lt;br /&gt;
  # Validations&lt;br /&gt;
  validates :subject, presence: true, length: { maximum: 255 }&lt;br /&gt;
  validates :description, presence: true&lt;br /&gt;
  validates :expiration_date, presence: true&lt;br /&gt;
  validate :expiration_date_cannot_be_in_the_past&lt;br /&gt;
  # Scopes&lt;br /&gt;
  scope :active, -&amp;gt; { where(active_flag: true) }&lt;br /&gt;
  scope :expired, -&amp;gt; { where('expiration_date &amp;lt; ?', Date.today) }&lt;br /&gt;
  scope :unread_by, -&amp;gt;(user) {&lt;br /&gt;
    joins(:course).where(courses: { id: user.assignments.pluck(:course_id) }).where(active_flag: true)&lt;br /&gt;
  }&lt;br /&gt;
  # Custom Validation for Expiration Date&lt;br /&gt;
  def expiration_date_cannot_be_in_the_past&lt;br /&gt;
    if expiration_date.present? &amp;amp;&amp;amp; expiration_date &amp;lt; Date.today&lt;br /&gt;
      errors.add(:expiration_date, &amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; 2. Controller for Notification (controllers/notification_controller.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/controllers/api/v1/notifications_controller.rb Commit]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class Api::V1::NotificationsController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
  before_action :set_notification, only: %i[show update destroy]&lt;br /&gt;
  # GET /notifications&lt;br /&gt;
  def index&lt;br /&gt;
    if current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      @notifications = Notification.where(user_id: current_user.id)&lt;br /&gt;
    elsif current_user_has_student_privileges?&lt;br /&gt;
      course_names = current_user.courses.pluck(:name)&lt;br /&gt;
      @notifications = Notification.where(course_name: course_names, active_flag: true)&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Access denied' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: @notifications&lt;br /&gt;
  end&lt;br /&gt;
  # GET /notifications/:id&lt;br /&gt;
  def show&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      render json: @notification&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You do not have access to this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # POST /notifications&lt;br /&gt;
  def create&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to create notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end &lt;br /&gt;
    @notification = Notification.new(notification_params)&lt;br /&gt;
    @notification.user_id = current_user.id&lt;br /&gt;
  &lt;br /&gt;
    if @notification.save&lt;br /&gt;
      render json: @notification, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH/PUT /notifications/:id&lt;br /&gt;
  def update&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to update notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.update(notification_params)&lt;br /&gt;
      render json: @notification, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # DELETE /notifications/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to delete notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.destroy&lt;br /&gt;
      render json: { message: 'Notification deleted successfully.' }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Failed to delete the notification.' }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH /notifications/:id/toggle_active&lt;br /&gt;
  def toggle_notification_visibility&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      @notification.update(active_flag: !@notification.active_flag)&lt;br /&gt;
      render json: { message: 'Notification visibility toggled successfully.', notification: @notification }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You are not authorized to toggle this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_notification&lt;br /&gt;
    @notification = Notification.find(params[:id])&lt;br /&gt;
  rescue ActiveRecord::RecordNotFound&lt;br /&gt;
    render json: { error: 'Notification not found.' }, status: :not_found&lt;br /&gt;
  end&lt;br /&gt;
  # Define strong parameters for notification creation/update&lt;br /&gt;
  def notification_params&lt;br /&gt;
    params.require(:notification).permit(:course_name, :subject, :description, :expiration_date, :active_flag)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method to check if a notification is accessible to the current user&lt;br /&gt;
  def notification_accessible?(notification)&lt;br /&gt;
    # Instructors and TAs can access their own notifications&lt;br /&gt;
    return true if notification.user_id == current_user.id&lt;br /&gt;
    # Students can access notifications for their courses&lt;br /&gt;
    return true if current_user_has_student_privileges? &amp;amp;&amp;amp;&lt;br /&gt;
                   current_user.courses.exists?(name: notification.course_name)&lt;br /&gt;
    false&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Patterns and SOLID principles uses=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Following are the some of the SOLID principles with how they will be applied to the back-end development:&amp;lt;/b&amp;gt;&lt;br /&gt;
* Single Responsibility : Controllers handle HTTP requests, models handle data, and service objects handle business logic (e.g., sending notifications).&lt;br /&gt;
* Open/Closed : Extend functionality (e.g., new notification types or filters) by adding new classes or methods without modifying existing code.&lt;br /&gt;
* Interface Segregation : Create small, role-specific interfaces (e.g., policies for TAs, students, instructors) and separate service objects for different types of notifications.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
This section outlines the comprehensive testing approach for the Notifications feature to ensure it meets functional and non-functional requirements. The strategy includes detailed test cases for models, controllers, role-based access, and error handling, leveraging RSpec for testing and RSwag for API documentation.&lt;br /&gt;
&lt;br /&gt;
'''1. Unit Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure that the Notification model functions as expected by validating its attributes, associations, and methods.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/spec/models/notification_spec.rb File as on GitHub]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
* Validations:&lt;br /&gt;
** Presence validation for subject, description, expiration_date, course_id, and user_id.&lt;br /&gt;
** Length constraints on subject and description.&lt;br /&gt;
** Format validation for expiration_date.&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :user and belongs_to :course associations are correctly established.&lt;br /&gt;
** Notifications have appropriate relationships with Course and User models.&lt;br /&gt;
&lt;br /&gt;
* Custom Methods and Scopes:&lt;br /&gt;
** active_notifications: Ensure only active notifications are returned.&lt;br /&gt;
** unread_notifications: Validate that unread notifications are fetched correctly.&lt;br /&gt;
&lt;br /&gt;
* Edge Cases:&lt;br /&gt;
** Notifications with an expired expiration_date should not appear in the active notifications list.&lt;br /&gt;
** Handling invalid foreign keys for user_id and course_id.&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe Notification, type: :model do&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it { should validate_presence_of(:subject) }&lt;br /&gt;
    it { should validate_presence_of(:description) }&lt;br /&gt;
    it { should validate_presence_of(:expiration_date) }&lt;br /&gt;
    it { should validate_length_of(:subject).is_at_most(100) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it { should belong_to(:user) }&lt;br /&gt;
    it { should belong_to(:course) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    let!(:active_notification) { create(:notification, is_active: true) }&lt;br /&gt;
    let!(:expired_notification) { create(:notification, expiration_date: Date.yesterday) }&lt;br /&gt;
    it 'returns active notifications' do&lt;br /&gt;
      expect(Notification.active_notifications).to include(active_notification)&lt;br /&gt;
      expect(Notification.active_notifications).not_to include(expired_notification)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Controller Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Test all CRUD operations for the Notifications controller to ensure endpoints function as expected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Index Action:&lt;br /&gt;
** Ensure all notifications for a given user are returned.&lt;br /&gt;
** Verify that unauthorized users cannot access the endpoint.&lt;br /&gt;
** Test paginated responses if applicable.&lt;br /&gt;
* Show Action:&lt;br /&gt;
** Ensure notifications can be retrieved by id.&lt;br /&gt;
** Handle cases where id is invalid or unauthorized.&lt;br /&gt;
* Create Action:&lt;br /&gt;
** Validate successful creation of notifications with proper attributes.&lt;br /&gt;
** Handle validation failures and unauthorized access.&lt;br /&gt;
* Update Action:&lt;br /&gt;
** Test updates to notification attributes.&lt;br /&gt;
** Ensure unauthorized users cannot perform updates.&lt;br /&gt;
* Delete Action:&lt;br /&gt;
** Verify notifications are deleted successfully.&lt;br /&gt;
** Test behavior when id is invalid or unauthorized.&lt;br /&gt;
&lt;br /&gt;
 require 'rails_helper'&lt;br /&gt;
 RSpec.describe Api::V1::NotificationsController, type: :controller do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let(:notification) { create(:notification) }&lt;br /&gt;
  describe 'GET #index' do&lt;br /&gt;
    before { sign_in admin }&lt;br /&gt;
    it 'returns notifications for the current user' do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:ok)&lt;br /&gt;
      expect(json_response).to include(notification)&lt;br /&gt;
    end&lt;br /&gt;
    it 'denies access to unauthorized users' do&lt;br /&gt;
      sign_out admin&lt;br /&gt;
      sign_in student&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:forbidden)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  describe 'POST #create' do&lt;br /&gt;
    context 'with valid attributes' do&lt;br /&gt;
      it 'creates a new notification' do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { notification: attributes_for(:notification) }&lt;br /&gt;
        }.to change(Notification, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'with invalid attributes' do&lt;br /&gt;
      it 'returns validation errors' do&lt;br /&gt;
        post :create, params: { notification: { subject: '' } }&lt;br /&gt;
        expect(response).to have_http_status(:unprocessable_entity)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''3. Integration Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure seamless interaction between models, controllers, and role-based access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Role-Based Access:&lt;br /&gt;
** Verify only authorized roles (e.g., Admin, Instructor) can manage notifications.&lt;br /&gt;
** Ensure students can only view notifications for their enrolled courses.&lt;br /&gt;
* Full CRUD Workflow:&lt;br /&gt;
** Test end-to-end creation, updating, and deletion of notifications.&lt;br /&gt;
* Error Scenarios:&lt;br /&gt;
** Handle cases where a notification is created for a non-existent course or user.&lt;br /&gt;
** Verify appropriate error messages for unauthorized actions.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications Integration', type: :request do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let!(:notification) { create(:notification, user: admin) }&lt;br /&gt;
  it 'allows admins to create notifications' do&lt;br /&gt;
    sign_in admin&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:created)&lt;br /&gt;
  end&lt;br /&gt;
  it 'prevents students from creating notifications' do&lt;br /&gt;
    sign_in student&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:forbidden)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''4. API Documentation and Testing with RSwag'''&lt;br /&gt;
&lt;br /&gt;
Goal: Generate API documentation and test all endpoints.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get 'Retrieve notifications' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      response '200', 'success' do&lt;br /&gt;
        schema type: :array, items: { type: :object, properties: { id: { type: :integer }, subject: { type: :string } } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    post 'Create a notification' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: 'date' },&lt;br /&gt;
          is_active: { type: :boolean }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject description expiration_date]&lt;br /&gt;
      }&lt;br /&gt;
      response '201', 'created' do&lt;br /&gt;
        let(:notification) { { subject: 'Test', description: 'Test notification', expiration_date: '2024-12-31', is_active: true } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;br /&gt;
* '''Demo Video Link''' []&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160691</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160691"/>
		<updated>2024-12-04T04:58:05Z</updated>

		<summary type="html">&lt;p&gt;Akilled: Undo revision 160689 by Akilled (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== New Files ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Model for Notification (models/notification.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/models/notification.rb Commit]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class Notification &amp;lt; ApplicationRecord&lt;br /&gt;
  # Associations&lt;br /&gt;
  belongs_to :course, foreign_key: :course_name, primary_key: :name&lt;br /&gt;
  belongs_to :user&lt;br /&gt;
  # Validations&lt;br /&gt;
  validates :subject, presence: true, length: { maximum: 255 }&lt;br /&gt;
  validates :description, presence: true&lt;br /&gt;
  validates :expiration_date, presence: true&lt;br /&gt;
  validate :expiration_date_cannot_be_in_the_past&lt;br /&gt;
  # Scopes&lt;br /&gt;
  scope :active, -&amp;gt; { where(active_flag: true) }&lt;br /&gt;
  scope :expired, -&amp;gt; { where('expiration_date &amp;lt; ?', Date.today) }&lt;br /&gt;
  scope :unread_by, -&amp;gt;(user) {&lt;br /&gt;
    joins(:course).where(courses: { id: user.assignments.pluck(:course_id) }).where(active_flag: true)&lt;br /&gt;
  }&lt;br /&gt;
  # Custom Validation for Expiration Date&lt;br /&gt;
  def expiration_date_cannot_be_in_the_past&lt;br /&gt;
    if expiration_date.present? &amp;amp;&amp;amp; expiration_date &amp;lt; Date.today&lt;br /&gt;
      errors.add(:expiration_date, &amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; 2. Controller for Notification (controllers/notification_controller.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/controllers/api/v1/notifications_controller.rb Commit]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class Api::V1::NotificationsController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
  before_action :set_notification, only: %i[show update destroy]&lt;br /&gt;
  # GET /notifications&lt;br /&gt;
  def index&lt;br /&gt;
    if current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      @notifications = Notification.where(user_id: current_user.id)&lt;br /&gt;
    elsif current_user_has_student_privileges?&lt;br /&gt;
      course_names = current_user.courses.pluck(:name)&lt;br /&gt;
      @notifications = Notification.where(course_name: course_names, active_flag: true)&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Access denied' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: @notifications&lt;br /&gt;
  end&lt;br /&gt;
  # GET /notifications/:id&lt;br /&gt;
  def show&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      render json: @notification&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You do not have access to this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # POST /notifications&lt;br /&gt;
  def create&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to create notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end &lt;br /&gt;
    @notification = Notification.new(notification_params)&lt;br /&gt;
    @notification.user_id = current_user.id&lt;br /&gt;
  &lt;br /&gt;
    if @notification.save&lt;br /&gt;
      render json: @notification, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH/PUT /notifications/:id&lt;br /&gt;
  def update&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to update notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.update(notification_params)&lt;br /&gt;
      render json: @notification, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # DELETE /notifications/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to delete notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.destroy&lt;br /&gt;
      render json: { message: 'Notification deleted successfully.' }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Failed to delete the notification.' }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH /notifications/:id/toggle_active&lt;br /&gt;
  def toggle_notification_visibility&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      @notification.update(active_flag: !@notification.active_flag)&lt;br /&gt;
      render json: { message: 'Notification visibility toggled successfully.', notification: @notification }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You are not authorized to toggle this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_notification&lt;br /&gt;
    @notification = Notification.find(params[:id])&lt;br /&gt;
  rescue ActiveRecord::RecordNotFound&lt;br /&gt;
    render json: { error: 'Notification not found.' }, status: :not_found&lt;br /&gt;
  end&lt;br /&gt;
  # Define strong parameters for notification creation/update&lt;br /&gt;
  def notification_params&lt;br /&gt;
    params.require(:notification).permit(:course_name, :subject, :description, :expiration_date, :active_flag)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method to check if a notification is accessible to the current user&lt;br /&gt;
  def notification_accessible?(notification)&lt;br /&gt;
    # Instructors and TAs can access their own notifications&lt;br /&gt;
    return true if notification.user_id == current_user.id&lt;br /&gt;
    # Students can access notifications for their courses&lt;br /&gt;
    return true if current_user_has_student_privileges? &amp;amp;&amp;amp;&lt;br /&gt;
                   current_user.courses.exists?(name: notification.course_name)&lt;br /&gt;
    false&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Patterns and SOLID principles uses=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Following are the some of the SOLID principles with how they will be applied to the back-end development:&amp;lt;/b&amp;gt;&lt;br /&gt;
* Single Responsibility : Controllers handle HTTP requests, models handle data, and service objects handle business logic (e.g., sending notifications).&lt;br /&gt;
* Open/Closed : Extend functionality (e.g., new notification types or filters) by adding new classes or methods without modifying existing code.&lt;br /&gt;
* Interface Segregation : Create small, role-specific interfaces (e.g., policies for TAs, students, instructors) and separate service objects for different types of notifications.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
This section outlines the comprehensive testing approach for the Notifications feature to ensure it meets functional and non-functional requirements. The strategy includes detailed test cases for models, controllers, role-based access, and error handling, leveraging RSpec for testing and RSwag for API documentation.&lt;br /&gt;
&lt;br /&gt;
'''1. Unit Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure that the Notification model functions as expected by validating its attributes, associations, and methods.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
* Validations:&lt;br /&gt;
** Presence validation for subject, description, expiration_date, course_id, and user_id.&lt;br /&gt;
** Length constraints on subject and description.&lt;br /&gt;
** Format validation for expiration_date.&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :user and belongs_to :course associations are correctly established.&lt;br /&gt;
** Notifications have appropriate relationships with Course and User models.&lt;br /&gt;
&lt;br /&gt;
* Custom Methods and Scopes:&lt;br /&gt;
** active_notifications: Ensure only active notifications are returned.&lt;br /&gt;
** unread_notifications: Validate that unread notifications are fetched correctly.&lt;br /&gt;
&lt;br /&gt;
* Edge Cases:&lt;br /&gt;
** Notifications with an expired expiration_date should not appear in the active notifications list.&lt;br /&gt;
** Handling invalid foreign keys for user_id and course_id.&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe Notification, type: :model do&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it { should validate_presence_of(:subject) }&lt;br /&gt;
    it { should validate_presence_of(:description) }&lt;br /&gt;
    it { should validate_presence_of(:expiration_date) }&lt;br /&gt;
    it { should validate_length_of(:subject).is_at_most(100) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it { should belong_to(:user) }&lt;br /&gt;
    it { should belong_to(:course) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    let!(:active_notification) { create(:notification, is_active: true) }&lt;br /&gt;
    let!(:expired_notification) { create(:notification, expiration_date: Date.yesterday) }&lt;br /&gt;
    it 'returns active notifications' do&lt;br /&gt;
      expect(Notification.active_notifications).to include(active_notification)&lt;br /&gt;
      expect(Notification.active_notifications).not_to include(expired_notification)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Controller Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Test all CRUD operations for the Notifications controller to ensure endpoints function as expected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Index Action:&lt;br /&gt;
** Ensure all notifications for a given user are returned.&lt;br /&gt;
** Verify that unauthorized users cannot access the endpoint.&lt;br /&gt;
** Test paginated responses if applicable.&lt;br /&gt;
* Show Action:&lt;br /&gt;
** Ensure notifications can be retrieved by id.&lt;br /&gt;
** Handle cases where id is invalid or unauthorized.&lt;br /&gt;
* Create Action:&lt;br /&gt;
** Validate successful creation of notifications with proper attributes.&lt;br /&gt;
** Handle validation failures and unauthorized access.&lt;br /&gt;
* Update Action:&lt;br /&gt;
** Test updates to notification attributes.&lt;br /&gt;
** Ensure unauthorized users cannot perform updates.&lt;br /&gt;
* Delete Action:&lt;br /&gt;
** Verify notifications are deleted successfully.&lt;br /&gt;
** Test behavior when id is invalid or unauthorized.&lt;br /&gt;
&lt;br /&gt;
 require 'rails_helper'&lt;br /&gt;
 RSpec.describe Api::V1::NotificationsController, type: :controller do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let(:notification) { create(:notification) }&lt;br /&gt;
  describe 'GET #index' do&lt;br /&gt;
    before { sign_in admin }&lt;br /&gt;
    it 'returns notifications for the current user' do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:ok)&lt;br /&gt;
      expect(json_response).to include(notification)&lt;br /&gt;
    end&lt;br /&gt;
    it 'denies access to unauthorized users' do&lt;br /&gt;
      sign_out admin&lt;br /&gt;
      sign_in student&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:forbidden)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  describe 'POST #create' do&lt;br /&gt;
    context 'with valid attributes' do&lt;br /&gt;
      it 'creates a new notification' do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { notification: attributes_for(:notification) }&lt;br /&gt;
        }.to change(Notification, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'with invalid attributes' do&lt;br /&gt;
      it 'returns validation errors' do&lt;br /&gt;
        post :create, params: { notification: { subject: '' } }&lt;br /&gt;
        expect(response).to have_http_status(:unprocessable_entity)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''3. Integration Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure seamless interaction between models, controllers, and role-based access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Role-Based Access:&lt;br /&gt;
** Verify only authorized roles (e.g., Admin, Instructor) can manage notifications.&lt;br /&gt;
** Ensure students can only view notifications for their enrolled courses.&lt;br /&gt;
* Full CRUD Workflow:&lt;br /&gt;
** Test end-to-end creation, updating, and deletion of notifications.&lt;br /&gt;
* Error Scenarios:&lt;br /&gt;
** Handle cases where a notification is created for a non-existent course or user.&lt;br /&gt;
** Verify appropriate error messages for unauthorized actions.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications Integration', type: :request do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let!(:notification) { create(:notification, user: admin) }&lt;br /&gt;
  it 'allows admins to create notifications' do&lt;br /&gt;
    sign_in admin&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:created)&lt;br /&gt;
  end&lt;br /&gt;
  it 'prevents students from creating notifications' do&lt;br /&gt;
    sign_in student&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:forbidden)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''4. API Documentation and Testing with RSwag'''&lt;br /&gt;
&lt;br /&gt;
Goal: Generate API documentation and test all endpoints.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get 'Retrieve notifications' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      response '200', 'success' do&lt;br /&gt;
        schema type: :array, items: { type: :object, properties: { id: { type: :integer }, subject: { type: :string } } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    post 'Create a notification' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: 'date' },&lt;br /&gt;
          is_active: { type: :boolean }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject description expiration_date]&lt;br /&gt;
      }&lt;br /&gt;
      response '201', 'created' do&lt;br /&gt;
        let(:notification) { { subject: 'Test', description: 'Test notification', expiration_date: '2024-12-31', is_active: true } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;br /&gt;
* '''Demo Video Link''' []&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160689</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160689"/>
		<updated>2024-12-04T04:57:47Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== New Files ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Model for Notification (models/notification.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/models/notification.rb Commit]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class Notification &amp;lt; ApplicationRecord&lt;br /&gt;
  # Associations&lt;br /&gt;
  belongs_to :course, foreign_key: :course_name, primary_key: :name&lt;br /&gt;
  belongs_to :user&lt;br /&gt;
  # Validations&lt;br /&gt;
  validates :subject, presence: true, length: { maximum: 255 }&lt;br /&gt;
  validates :description, presence: true&lt;br /&gt;
  validates :expiration_date, presence: true&lt;br /&gt;
  validate :expiration_date_cannot_be_in_the_past&lt;br /&gt;
  # Scopes&lt;br /&gt;
  scope :active, -&amp;gt; { where(active_flag: true) }&lt;br /&gt;
  scope :expired, -&amp;gt; { where('expiration_date &amp;lt; ?', Date.today) }&lt;br /&gt;
  scope :unread_by, -&amp;gt;(user) {&lt;br /&gt;
    joins(:course).where(courses: { id: user.assignments.pluck(:course_id) }).where(active_flag: true)&lt;br /&gt;
  }&lt;br /&gt;
  # Custom Validation for Expiration Date&lt;br /&gt;
  def expiration_date_cannot_be_in_the_past&lt;br /&gt;
    if expiration_date.present? &amp;amp;&amp;amp; expiration_date &amp;lt; Date.today&lt;br /&gt;
      errors.add(:expiration_date, &amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; 2. Controller for Notification (controllers/notification_controller.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/controllers/api/v1/notifications_controller.rb Commit]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class Api::V1::NotificationsController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
  before_action :set_notification, only: %i[show update destroy]&lt;br /&gt;
  # GET /notifications&lt;br /&gt;
  def index&lt;br /&gt;
    if current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      @notifications = Notification.where(user_id: current_user.id)&lt;br /&gt;
    elsif current_user_has_student_privileges?&lt;br /&gt;
      course_names = current_user.courses.pluck(:name)&lt;br /&gt;
      @notifications = Notification.where(course_name: course_names, active_flag: true)&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Access denied' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: @notifications&lt;br /&gt;
  end&lt;br /&gt;
  # GET /notifications/:id&lt;br /&gt;
  def show&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      render json: @notification&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You do not have access to this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # POST /notifications&lt;br /&gt;
  def create&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to create notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end &lt;br /&gt;
    @notification = Notification.new(notification_params)&lt;br /&gt;
    @notification.user_id = current_user.id&lt;br /&gt;
  &lt;br /&gt;
    if @notification.save&lt;br /&gt;
      render json: @notification, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH/PUT /notifications/:id&lt;br /&gt;
  def update&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to update notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.update(notification_params)&lt;br /&gt;
      render json: @notification, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # DELETE /notifications/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to delete notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.destroy&lt;br /&gt;
      render json: { message: 'Notification deleted successfully.' }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Failed to delete the notification.' }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH /notifications/:id/toggle_active&lt;br /&gt;
  def toggle_notification_visibility&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      @notification.update(active_flag: !@notification.active_flag)&lt;br /&gt;
      render json: { message: 'Notification visibility toggled successfully.', notification: @notification }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You are not authorized to toggle this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_notification&lt;br /&gt;
    @notification = Notification.find(params[:id])&lt;br /&gt;
  rescue ActiveRecord::RecordNotFound&lt;br /&gt;
    render json: { error: 'Notification not found.' }, status: :not_found&lt;br /&gt;
  end&lt;br /&gt;
  # Define strong parameters for notification creation/update&lt;br /&gt;
  def notification_params&lt;br /&gt;
    params.require(:notification).permit(:course_name, :subject, :description, :expiration_date, :active_flag)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method to check if a notification is accessible to the current user&lt;br /&gt;
  def notification_accessible?(notification)&lt;br /&gt;
    # Instructors and TAs can access their own notifications&lt;br /&gt;
    return true if notification.user_id == current_user.id&lt;br /&gt;
    # Students can access notifications for their courses&lt;br /&gt;
    return true if current_user_has_student_privileges? &amp;amp;&amp;amp;&lt;br /&gt;
                   current_user.courses.exists?(name: notification.course_name)&lt;br /&gt;
    false&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Patterns and SOLID principles uses=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Following are the some of the SOLID principles with how they will be applied to the back-end development:&amp;lt;/b&amp;gt;&lt;br /&gt;
* Single Responsibility : Controllers handle HTTP requests, models handle data, and service objects handle business logic (e.g., sending notifications).&lt;br /&gt;
* Open/Closed : Extend functionality (e.g., new notification types or filters) by adding new classes or methods without modifying existing code.&lt;br /&gt;
* Interface Segregation : Create small, role-specific interfaces (e.g., policies for TAs, students, instructors) and separate service objects for different types of notifications.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
This section outlines the comprehensive testing approach for the Notifications feature to ensure it meets functional and non-functional requirements. The strategy includes detailed test cases for models, controllers, role-based access, and error handling, leveraging RSpec for testing and RSwag for API documentation.&lt;br /&gt;
&lt;br /&gt;
'''1. Unit Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure that the Notification model functions as expected by validating its attributes, associations, and methods.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
* Validations:&lt;br /&gt;
** Presence validation for subject, description, expiration_date, course_id, and user_id.&lt;br /&gt;
** Length constraints on subject and description.&lt;br /&gt;
** Format validation for expiration_date.&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :user and belongs_to :course associations are correctly established.&lt;br /&gt;
** Notifications have appropriate relationships with Course and User models.&lt;br /&gt;
&lt;br /&gt;
* Custom Methods and Scopes:&lt;br /&gt;
** active_notifications: Ensure only active notifications are returned.&lt;br /&gt;
** unread_notifications: Validate that unread notifications are fetched correctly.&lt;br /&gt;
&lt;br /&gt;
* Edge Cases:&lt;br /&gt;
** Notifications with an expired expiration_date should not appear in the active notifications list.&lt;br /&gt;
** Handling invalid foreign keys for user_id and course_id.&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
&lt;br /&gt;
RSpec.describe Notification, type: :model do&lt;br /&gt;
  before(:each) do&lt;br /&gt;
    # Mock the course and user&lt;br /&gt;
    @course = instance_double(Course, name: &amp;quot;Ruby 101&amp;quot;)&lt;br /&gt;
    role = instance_double(Role, id: 1, name: &amp;quot;Student&amp;quot;)&lt;br /&gt;
    @user = instance_double(User, id: 1, name: &amp;quot;Test User&amp;quot;, email: &amp;quot;test@example.com&amp;quot;, role: role)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it 'is invalid without a subject' do&lt;br /&gt;
      notification = Notification.new(subject: nil)&lt;br /&gt;
      expect(notification).not_to be_valid&lt;br /&gt;
      expect(notification.errors[:subject]).to include(&amp;quot;can't be blank&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'is invalid without a description' do&lt;br /&gt;
      notification = Notification.new(description: nil)&lt;br /&gt;
      expect(notification).not_to be_valid&lt;br /&gt;
      expect(notification.errors[:description]).to include(&amp;quot;can't be blank&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'is invalid without an expiration_date' do&lt;br /&gt;
      notification = Notification.new(expiration_date: nil)&lt;br /&gt;
      expect(notification).not_to be_valid&lt;br /&gt;
      expect(notification.errors[:expiration_date]).to include(&amp;quot;can't be blank&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'is invalid if expiration_date is in the past' do&lt;br /&gt;
      notification = Notification.new(expiration_date: Date.yesterday)&lt;br /&gt;
      expect(notification).not_to be_valid&lt;br /&gt;
      expect(notification.errors[:expiration_date]).to include(&amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it 'belongs to a course' do&lt;br /&gt;
      # Mock the course association&lt;br /&gt;
      notification = Notification.new&lt;br /&gt;
      allow(notification).to receive(:course).and_return(@course)&lt;br /&gt;
&lt;br /&gt;
      # Test that the association returns the mocked course&lt;br /&gt;
      expect(notification.course).to eq(@course)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'belongs to a user' do&lt;br /&gt;
      # Mock the user association&lt;br /&gt;
      notification = Notification.new&lt;br /&gt;
      allow(notification).to receive(:user).and_return(@user)&lt;br /&gt;
&lt;br /&gt;
      # Test that the association returns the mocked user&lt;br /&gt;
      expect(notification.user).to eq(@user)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      @notification1 = instance_double(&lt;br /&gt;
        Notification,&lt;br /&gt;
        subject: &amp;quot;Active Notification&amp;quot;,&lt;br /&gt;
        expiration_date: Date.today + 3,&lt;br /&gt;
        active_flag: true,&lt;br /&gt;
        course_name: @course.name,&lt;br /&gt;
        user: @user&lt;br /&gt;
      )&lt;br /&gt;
&lt;br /&gt;
      @notification2 = instance_double(&lt;br /&gt;
        Notification,&lt;br /&gt;
        subject: &amp;quot;Expired Notification&amp;quot;,&lt;br /&gt;
        expiration_date: Date.yesterday,&lt;br /&gt;
        active_flag: true,&lt;br /&gt;
        course_name: @course.name,&lt;br /&gt;
        user: @user&lt;br /&gt;
      )&lt;br /&gt;
&lt;br /&gt;
      @notification3 = instance_double(&lt;br /&gt;
        Notification,&lt;br /&gt;
        subject: &amp;quot;Inactive Notification&amp;quot;,&lt;br /&gt;
        expiration_date: Date.today + 7,&lt;br /&gt;
        active_flag: false,&lt;br /&gt;
        course_name: @course.name,&lt;br /&gt;
        user: @user&lt;br /&gt;
      )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    describe '.active' do&lt;br /&gt;
      it 'returns notifications that are active' do&lt;br /&gt;
        allow(Notification).to receive(:active).and_return([@notification1])&lt;br /&gt;
        expect(Notification.active).to include(@notification1)&lt;br /&gt;
        expect(Notification.active).not_to include(@notification2, @notification3)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    describe '.expired' do&lt;br /&gt;
      it 'returns notifications that are expired' do&lt;br /&gt;
        allow(Notification).to receive(:expired).and_return([@notification2])&lt;br /&gt;
        expect(Notification.expired).to include(@notification2)&lt;br /&gt;
        expect(Notification.expired).not_to include(@notification1, @notification3)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    describe '.unread_by' do&lt;br /&gt;
      it 'returns notifications that are unread by the user' do&lt;br /&gt;
        allow(Notification).to receive(:unread_by).with(@user).and_return([@notification1])&lt;br /&gt;
        unread_notifications = Notification.unread_by(@user)&lt;br /&gt;
        expect(unread_notifications).to include(@notification1)&lt;br /&gt;
        expect(unread_notifications).not_to include(@notification2, @notification3)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
'''2. Controller Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Test all CRUD operations for the Notifications controller to ensure endpoints function as expected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Index Action:&lt;br /&gt;
** Ensure all notifications for a given user are returned.&lt;br /&gt;
** Verify that unauthorized users cannot access the endpoint.&lt;br /&gt;
** Test paginated responses if applicable.&lt;br /&gt;
* Show Action:&lt;br /&gt;
** Ensure notifications can be retrieved by id.&lt;br /&gt;
** Handle cases where id is invalid or unauthorized.&lt;br /&gt;
* Create Action:&lt;br /&gt;
** Validate successful creation of notifications with proper attributes.&lt;br /&gt;
** Handle validation failures and unauthorized access.&lt;br /&gt;
* Update Action:&lt;br /&gt;
** Test updates to notification attributes.&lt;br /&gt;
** Ensure unauthorized users cannot perform updates.&lt;br /&gt;
* Delete Action:&lt;br /&gt;
** Verify notifications are deleted successfully.&lt;br /&gt;
** Test behavior when id is invalid or unauthorized.&lt;br /&gt;
&lt;br /&gt;
 require 'rails_helper'&lt;br /&gt;
 RSpec.describe Api::V1::NotificationsController, type: :controller do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let(:notification) { create(:notification) }&lt;br /&gt;
  describe 'GET #index' do&lt;br /&gt;
    before { sign_in admin }&lt;br /&gt;
    it 'returns notifications for the current user' do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:ok)&lt;br /&gt;
      expect(json_response).to include(notification)&lt;br /&gt;
    end&lt;br /&gt;
    it 'denies access to unauthorized users' do&lt;br /&gt;
      sign_out admin&lt;br /&gt;
      sign_in student&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:forbidden)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  describe 'POST #create' do&lt;br /&gt;
    context 'with valid attributes' do&lt;br /&gt;
      it 'creates a new notification' do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { notification: attributes_for(:notification) }&lt;br /&gt;
        }.to change(Notification, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'with invalid attributes' do&lt;br /&gt;
      it 'returns validation errors' do&lt;br /&gt;
        post :create, params: { notification: { subject: '' } }&lt;br /&gt;
        expect(response).to have_http_status(:unprocessable_entity)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''3. Integration Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure seamless interaction between models, controllers, and role-based access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Role-Based Access:&lt;br /&gt;
** Verify only authorized roles (e.g., Admin, Instructor) can manage notifications.&lt;br /&gt;
** Ensure students can only view notifications for their enrolled courses.&lt;br /&gt;
* Full CRUD Workflow:&lt;br /&gt;
** Test end-to-end creation, updating, and deletion of notifications.&lt;br /&gt;
* Error Scenarios:&lt;br /&gt;
** Handle cases where a notification is created for a non-existent course or user.&lt;br /&gt;
** Verify appropriate error messages for unauthorized actions.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications Integration', type: :request do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let!(:notification) { create(:notification, user: admin) }&lt;br /&gt;
  it 'allows admins to create notifications' do&lt;br /&gt;
    sign_in admin&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:created)&lt;br /&gt;
  end&lt;br /&gt;
  it 'prevents students from creating notifications' do&lt;br /&gt;
    sign_in student&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:forbidden)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''4. API Documentation and Testing with RSwag'''&lt;br /&gt;
&lt;br /&gt;
Goal: Generate API documentation and test all endpoints.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get 'Retrieve notifications' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      response '200', 'success' do&lt;br /&gt;
        schema type: :array, items: { type: :object, properties: { id: { type: :integer }, subject: { type: :string } } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    post 'Create a notification' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: 'date' },&lt;br /&gt;
          is_active: { type: :boolean }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject description expiration_date]&lt;br /&gt;
      }&lt;br /&gt;
      response '201', 'created' do&lt;br /&gt;
        let(:notification) { { subject: 'Test', description: 'Test notification', expiration_date: '2024-12-31', is_active: true } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;br /&gt;
* '''Demo Video Link''' []&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160687</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160687"/>
		<updated>2024-12-04T04:56:26Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* Relevant Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== New Files ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Model for Notification (models/notification.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/models/notification.rb Commit]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class Notification &amp;lt; ApplicationRecord&lt;br /&gt;
  # Associations&lt;br /&gt;
  belongs_to :course, foreign_key: :course_name, primary_key: :name&lt;br /&gt;
  belongs_to :user&lt;br /&gt;
  # Validations&lt;br /&gt;
  validates :subject, presence: true, length: { maximum: 255 }&lt;br /&gt;
  validates :description, presence: true&lt;br /&gt;
  validates :expiration_date, presence: true&lt;br /&gt;
  validate :expiration_date_cannot_be_in_the_past&lt;br /&gt;
  # Scopes&lt;br /&gt;
  scope :active, -&amp;gt; { where(active_flag: true) }&lt;br /&gt;
  scope :expired, -&amp;gt; { where('expiration_date &amp;lt; ?', Date.today) }&lt;br /&gt;
  scope :unread_by, -&amp;gt;(user) {&lt;br /&gt;
    joins(:course).where(courses: { id: user.assignments.pluck(:course_id) }).where(active_flag: true)&lt;br /&gt;
  }&lt;br /&gt;
  # Custom Validation for Expiration Date&lt;br /&gt;
  def expiration_date_cannot_be_in_the_past&lt;br /&gt;
    if expiration_date.present? &amp;amp;&amp;amp; expiration_date &amp;lt; Date.today&lt;br /&gt;
      errors.add(:expiration_date, &amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; 2. Controller for Notification (controllers/notification_controller.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/controllers/api/v1/notifications_controller.rb Commit]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class Api::V1::NotificationsController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
  before_action :set_notification, only: %i[show update destroy]&lt;br /&gt;
  # GET /notifications&lt;br /&gt;
  def index&lt;br /&gt;
    if current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      @notifications = Notification.where(user_id: current_user.id)&lt;br /&gt;
    elsif current_user_has_student_privileges?&lt;br /&gt;
      course_names = current_user.courses.pluck(:name)&lt;br /&gt;
      @notifications = Notification.where(course_name: course_names, active_flag: true)&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Access denied' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: @notifications&lt;br /&gt;
  end&lt;br /&gt;
  # GET /notifications/:id&lt;br /&gt;
  def show&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      render json: @notification&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You do not have access to this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # POST /notifications&lt;br /&gt;
  def create&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to create notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end &lt;br /&gt;
    @notification = Notification.new(notification_params)&lt;br /&gt;
    @notification.user_id = current_user.id&lt;br /&gt;
  &lt;br /&gt;
    if @notification.save&lt;br /&gt;
      render json: @notification, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH/PUT /notifications/:id&lt;br /&gt;
  def update&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to update notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.update(notification_params)&lt;br /&gt;
      render json: @notification, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # DELETE /notifications/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to delete notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.destroy&lt;br /&gt;
      render json: { message: 'Notification deleted successfully.' }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Failed to delete the notification.' }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH /notifications/:id/toggle_active&lt;br /&gt;
  def toggle_notification_visibility&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      @notification.update(active_flag: !@notification.active_flag)&lt;br /&gt;
      render json: { message: 'Notification visibility toggled successfully.', notification: @notification }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You are not authorized to toggle this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_notification&lt;br /&gt;
    @notification = Notification.find(params[:id])&lt;br /&gt;
  rescue ActiveRecord::RecordNotFound&lt;br /&gt;
    render json: { error: 'Notification not found.' }, status: :not_found&lt;br /&gt;
  end&lt;br /&gt;
  # Define strong parameters for notification creation/update&lt;br /&gt;
  def notification_params&lt;br /&gt;
    params.require(:notification).permit(:course_name, :subject, :description, :expiration_date, :active_flag)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method to check if a notification is accessible to the current user&lt;br /&gt;
  def notification_accessible?(notification)&lt;br /&gt;
    # Instructors and TAs can access their own notifications&lt;br /&gt;
    return true if notification.user_id == current_user.id&lt;br /&gt;
    # Students can access notifications for their courses&lt;br /&gt;
    return true if current_user_has_student_privileges? &amp;amp;&amp;amp;&lt;br /&gt;
                   current_user.courses.exists?(name: notification.course_name)&lt;br /&gt;
    false&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Patterns and SOLID principles uses=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Following are the some of the SOLID principles with how they will be applied to the back-end development:&amp;lt;/b&amp;gt;&lt;br /&gt;
* Single Responsibility : Controllers handle HTTP requests, models handle data, and service objects handle business logic (e.g., sending notifications).&lt;br /&gt;
* Open/Closed : Extend functionality (e.g., new notification types or filters) by adding new classes or methods without modifying existing code.&lt;br /&gt;
* Interface Segregation : Create small, role-specific interfaces (e.g., policies for TAs, students, instructors) and separate service objects for different types of notifications.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
This section outlines the comprehensive testing approach for the Notifications feature to ensure it meets functional and non-functional requirements. The strategy includes detailed test cases for models, controllers, role-based access, and error handling, leveraging RSpec for testing and RSwag for API documentation.&lt;br /&gt;
&lt;br /&gt;
'''1. Unit Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure that the Notification model functions as expected by validating its attributes, associations, and methods.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
* Validations:&lt;br /&gt;
** Presence validation for subject, description, expiration_date, course_id, and user_id.&lt;br /&gt;
** Length constraints on subject and description.&lt;br /&gt;
** Format validation for expiration_date.&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :user and belongs_to :course associations are correctly established.&lt;br /&gt;
** Notifications have appropriate relationships with Course and User models.&lt;br /&gt;
&lt;br /&gt;
* Custom Methods and Scopes:&lt;br /&gt;
** active_notifications: Ensure only active notifications are returned.&lt;br /&gt;
** unread_notifications: Validate that unread notifications are fetched correctly.&lt;br /&gt;
&lt;br /&gt;
* Edge Cases:&lt;br /&gt;
** Notifications with an expired expiration_date should not appear in the active notifications list.&lt;br /&gt;
** Handling invalid foreign keys for user_id and course_id.&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe Notification, type: :model do&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it { should validate_presence_of(:subject) }&lt;br /&gt;
    it { should validate_presence_of(:description) }&lt;br /&gt;
    it { should validate_presence_of(:expiration_date) }&lt;br /&gt;
    it { should validate_length_of(:subject).is_at_most(100) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it { should belong_to(:user) }&lt;br /&gt;
    it { should belong_to(:course) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    let!(:active_notification) { create(:notification, is_active: true) }&lt;br /&gt;
    let!(:expired_notification) { create(:notification, expiration_date: Date.yesterday) }&lt;br /&gt;
    it 'returns active notifications' do&lt;br /&gt;
      expect(Notification.active_notifications).to include(active_notification)&lt;br /&gt;
      expect(Notification.active_notifications).not_to include(expired_notification)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Controller Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Test all CRUD operations for the Notifications controller to ensure endpoints function as expected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Index Action:&lt;br /&gt;
** Ensure all notifications for a given user are returned.&lt;br /&gt;
** Verify that unauthorized users cannot access the endpoint.&lt;br /&gt;
** Test paginated responses if applicable.&lt;br /&gt;
* Show Action:&lt;br /&gt;
** Ensure notifications can be retrieved by id.&lt;br /&gt;
** Handle cases where id is invalid or unauthorized.&lt;br /&gt;
* Create Action:&lt;br /&gt;
** Validate successful creation of notifications with proper attributes.&lt;br /&gt;
** Handle validation failures and unauthorized access.&lt;br /&gt;
* Update Action:&lt;br /&gt;
** Test updates to notification attributes.&lt;br /&gt;
** Ensure unauthorized users cannot perform updates.&lt;br /&gt;
* Delete Action:&lt;br /&gt;
** Verify notifications are deleted successfully.&lt;br /&gt;
** Test behavior when id is invalid or unauthorized.&lt;br /&gt;
&lt;br /&gt;
 require 'rails_helper'&lt;br /&gt;
 RSpec.describe Api::V1::NotificationsController, type: :controller do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let(:notification) { create(:notification) }&lt;br /&gt;
  describe 'GET #index' do&lt;br /&gt;
    before { sign_in admin }&lt;br /&gt;
    it 'returns notifications for the current user' do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:ok)&lt;br /&gt;
      expect(json_response).to include(notification)&lt;br /&gt;
    end&lt;br /&gt;
    it 'denies access to unauthorized users' do&lt;br /&gt;
      sign_out admin&lt;br /&gt;
      sign_in student&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:forbidden)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  describe 'POST #create' do&lt;br /&gt;
    context 'with valid attributes' do&lt;br /&gt;
      it 'creates a new notification' do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { notification: attributes_for(:notification) }&lt;br /&gt;
        }.to change(Notification, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'with invalid attributes' do&lt;br /&gt;
      it 'returns validation errors' do&lt;br /&gt;
        post :create, params: { notification: { subject: '' } }&lt;br /&gt;
        expect(response).to have_http_status(:unprocessable_entity)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''3. Integration Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure seamless interaction between models, controllers, and role-based access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Role-Based Access:&lt;br /&gt;
** Verify only authorized roles (e.g., Admin, Instructor) can manage notifications.&lt;br /&gt;
** Ensure students can only view notifications for their enrolled courses.&lt;br /&gt;
* Full CRUD Workflow:&lt;br /&gt;
** Test end-to-end creation, updating, and deletion of notifications.&lt;br /&gt;
* Error Scenarios:&lt;br /&gt;
** Handle cases where a notification is created for a non-existent course or user.&lt;br /&gt;
** Verify appropriate error messages for unauthorized actions.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications Integration', type: :request do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let!(:notification) { create(:notification, user: admin) }&lt;br /&gt;
  it 'allows admins to create notifications' do&lt;br /&gt;
    sign_in admin&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:created)&lt;br /&gt;
  end&lt;br /&gt;
  it 'prevents students from creating notifications' do&lt;br /&gt;
    sign_in student&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:forbidden)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''4. API Documentation and Testing with RSwag'''&lt;br /&gt;
&lt;br /&gt;
Goal: Generate API documentation and test all endpoints.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get 'Retrieve notifications' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      response '200', 'success' do&lt;br /&gt;
        schema type: :array, items: { type: :object, properties: { id: { type: :integer }, subject: { type: :string } } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    post 'Create a notification' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: 'date' },&lt;br /&gt;
          is_active: { type: :boolean }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject description expiration_date]&lt;br /&gt;
      }&lt;br /&gt;
      response '201', 'created' do&lt;br /&gt;
        let(:notification) { { subject: 'Test', description: 'Test notification', expiration_date: '2024-12-31', is_active: true } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;br /&gt;
* '''Demo Video Link''' []&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160686</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160686"/>
		<updated>2024-12-04T04:56:04Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* Design Pattern */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== New Files ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Model for Notification (models/notification.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/models/notification.rb Commit]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class Notification &amp;lt; ApplicationRecord&lt;br /&gt;
  # Associations&lt;br /&gt;
  belongs_to :course, foreign_key: :course_name, primary_key: :name&lt;br /&gt;
  belongs_to :user&lt;br /&gt;
  # Validations&lt;br /&gt;
  validates :subject, presence: true, length: { maximum: 255 }&lt;br /&gt;
  validates :description, presence: true&lt;br /&gt;
  validates :expiration_date, presence: true&lt;br /&gt;
  validate :expiration_date_cannot_be_in_the_past&lt;br /&gt;
  # Scopes&lt;br /&gt;
  scope :active, -&amp;gt; { where(active_flag: true) }&lt;br /&gt;
  scope :expired, -&amp;gt; { where('expiration_date &amp;lt; ?', Date.today) }&lt;br /&gt;
  scope :unread_by, -&amp;gt;(user) {&lt;br /&gt;
    joins(:course).where(courses: { id: user.assignments.pluck(:course_id) }).where(active_flag: true)&lt;br /&gt;
  }&lt;br /&gt;
  # Custom Validation for Expiration Date&lt;br /&gt;
  def expiration_date_cannot_be_in_the_past&lt;br /&gt;
    if expiration_date.present? &amp;amp;&amp;amp; expiration_date &amp;lt; Date.today&lt;br /&gt;
      errors.add(:expiration_date, &amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; 2. Controller for Notification (controllers/notification_controller.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/controllers/api/v1/notifications_controller.rb Commit]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class Api::V1::NotificationsController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
  before_action :set_notification, only: %i[show update destroy]&lt;br /&gt;
  # GET /notifications&lt;br /&gt;
  def index&lt;br /&gt;
    if current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      @notifications = Notification.where(user_id: current_user.id)&lt;br /&gt;
    elsif current_user_has_student_privileges?&lt;br /&gt;
      course_names = current_user.courses.pluck(:name)&lt;br /&gt;
      @notifications = Notification.where(course_name: course_names, active_flag: true)&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Access denied' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: @notifications&lt;br /&gt;
  end&lt;br /&gt;
  # GET /notifications/:id&lt;br /&gt;
  def show&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      render json: @notification&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You do not have access to this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # POST /notifications&lt;br /&gt;
  def create&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to create notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end &lt;br /&gt;
    @notification = Notification.new(notification_params)&lt;br /&gt;
    @notification.user_id = current_user.id&lt;br /&gt;
  &lt;br /&gt;
    if @notification.save&lt;br /&gt;
      render json: @notification, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH/PUT /notifications/:id&lt;br /&gt;
  def update&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to update notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.update(notification_params)&lt;br /&gt;
      render json: @notification, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # DELETE /notifications/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to delete notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.destroy&lt;br /&gt;
      render json: { message: 'Notification deleted successfully.' }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Failed to delete the notification.' }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH /notifications/:id/toggle_active&lt;br /&gt;
  def toggle_notification_visibility&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      @notification.update(active_flag: !@notification.active_flag)&lt;br /&gt;
      render json: { message: 'Notification visibility toggled successfully.', notification: @notification }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You are not authorized to toggle this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_notification&lt;br /&gt;
    @notification = Notification.find(params[:id])&lt;br /&gt;
  rescue ActiveRecord::RecordNotFound&lt;br /&gt;
    render json: { error: 'Notification not found.' }, status: :not_found&lt;br /&gt;
  end&lt;br /&gt;
  # Define strong parameters for notification creation/update&lt;br /&gt;
  def notification_params&lt;br /&gt;
    params.require(:notification).permit(:course_name, :subject, :description, :expiration_date, :active_flag)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method to check if a notification is accessible to the current user&lt;br /&gt;
  def notification_accessible?(notification)&lt;br /&gt;
    # Instructors and TAs can access their own notifications&lt;br /&gt;
    return true if notification.user_id == current_user.id&lt;br /&gt;
    # Students can access notifications for their courses&lt;br /&gt;
    return true if current_user_has_student_privileges? &amp;amp;&amp;amp;&lt;br /&gt;
                   current_user.courses.exists?(name: notification.course_name)&lt;br /&gt;
    false&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Patterns and SOLID principles uses=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Following are the some of the SOLID principles with how they will be applied to the back-end development:&amp;lt;/b&amp;gt;&lt;br /&gt;
* Single Responsibility : Controllers handle HTTP requests, models handle data, and service objects handle business logic (e.g., sending notifications).&lt;br /&gt;
* Open/Closed : Extend functionality (e.g., new notification types or filters) by adding new classes or methods without modifying existing code.&lt;br /&gt;
* Interface Segregation : Create small, role-specific interfaces (e.g., policies for TAs, students, instructors) and separate service objects for different types of notifications.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
This section outlines the comprehensive testing approach for the Notifications feature to ensure it meets functional and non-functional requirements. The strategy includes detailed test cases for models, controllers, role-based access, and error handling, leveraging RSpec for testing and RSwag for API documentation.&lt;br /&gt;
&lt;br /&gt;
'''1. Unit Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure that the Notification model functions as expected by validating its attributes, associations, and methods.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
* Validations:&lt;br /&gt;
** Presence validation for subject, description, expiration_date, course_id, and user_id.&lt;br /&gt;
** Length constraints on subject and description.&lt;br /&gt;
** Format validation for expiration_date.&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :user and belongs_to :course associations are correctly established.&lt;br /&gt;
** Notifications have appropriate relationships with Course and User models.&lt;br /&gt;
&lt;br /&gt;
* Custom Methods and Scopes:&lt;br /&gt;
** active_notifications: Ensure only active notifications are returned.&lt;br /&gt;
** unread_notifications: Validate that unread notifications are fetched correctly.&lt;br /&gt;
&lt;br /&gt;
* Edge Cases:&lt;br /&gt;
** Notifications with an expired expiration_date should not appear in the active notifications list.&lt;br /&gt;
** Handling invalid foreign keys for user_id and course_id.&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe Notification, type: :model do&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it { should validate_presence_of(:subject) }&lt;br /&gt;
    it { should validate_presence_of(:description) }&lt;br /&gt;
    it { should validate_presence_of(:expiration_date) }&lt;br /&gt;
    it { should validate_length_of(:subject).is_at_most(100) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it { should belong_to(:user) }&lt;br /&gt;
    it { should belong_to(:course) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    let!(:active_notification) { create(:notification, is_active: true) }&lt;br /&gt;
    let!(:expired_notification) { create(:notification, expiration_date: Date.yesterday) }&lt;br /&gt;
    it 'returns active notifications' do&lt;br /&gt;
      expect(Notification.active_notifications).to include(active_notification)&lt;br /&gt;
      expect(Notification.active_notifications).not_to include(expired_notification)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Controller Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Test all CRUD operations for the Notifications controller to ensure endpoints function as expected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Index Action:&lt;br /&gt;
** Ensure all notifications for a given user are returned.&lt;br /&gt;
** Verify that unauthorized users cannot access the endpoint.&lt;br /&gt;
** Test paginated responses if applicable.&lt;br /&gt;
* Show Action:&lt;br /&gt;
** Ensure notifications can be retrieved by id.&lt;br /&gt;
** Handle cases where id is invalid or unauthorized.&lt;br /&gt;
* Create Action:&lt;br /&gt;
** Validate successful creation of notifications with proper attributes.&lt;br /&gt;
** Handle validation failures and unauthorized access.&lt;br /&gt;
* Update Action:&lt;br /&gt;
** Test updates to notification attributes.&lt;br /&gt;
** Ensure unauthorized users cannot perform updates.&lt;br /&gt;
* Delete Action:&lt;br /&gt;
** Verify notifications are deleted successfully.&lt;br /&gt;
** Test behavior when id is invalid or unauthorized.&lt;br /&gt;
&lt;br /&gt;
 require 'rails_helper'&lt;br /&gt;
 RSpec.describe Api::V1::NotificationsController, type: :controller do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let(:notification) { create(:notification) }&lt;br /&gt;
  describe 'GET #index' do&lt;br /&gt;
    before { sign_in admin }&lt;br /&gt;
    it 'returns notifications for the current user' do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:ok)&lt;br /&gt;
      expect(json_response).to include(notification)&lt;br /&gt;
    end&lt;br /&gt;
    it 'denies access to unauthorized users' do&lt;br /&gt;
      sign_out admin&lt;br /&gt;
      sign_in student&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:forbidden)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  describe 'POST #create' do&lt;br /&gt;
    context 'with valid attributes' do&lt;br /&gt;
      it 'creates a new notification' do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { notification: attributes_for(:notification) }&lt;br /&gt;
        }.to change(Notification, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'with invalid attributes' do&lt;br /&gt;
      it 'returns validation errors' do&lt;br /&gt;
        post :create, params: { notification: { subject: '' } }&lt;br /&gt;
        expect(response).to have_http_status(:unprocessable_entity)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''3. Integration Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure seamless interaction between models, controllers, and role-based access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Role-Based Access:&lt;br /&gt;
** Verify only authorized roles (e.g., Admin, Instructor) can manage notifications.&lt;br /&gt;
** Ensure students can only view notifications for their enrolled courses.&lt;br /&gt;
* Full CRUD Workflow:&lt;br /&gt;
** Test end-to-end creation, updating, and deletion of notifications.&lt;br /&gt;
* Error Scenarios:&lt;br /&gt;
** Handle cases where a notification is created for a non-existent course or user.&lt;br /&gt;
** Verify appropriate error messages for unauthorized actions.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications Integration', type: :request do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let!(:notification) { create(:notification, user: admin) }&lt;br /&gt;
  it 'allows admins to create notifications' do&lt;br /&gt;
    sign_in admin&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:created)&lt;br /&gt;
  end&lt;br /&gt;
  it 'prevents students from creating notifications' do&lt;br /&gt;
    sign_in student&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:forbidden)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''4. API Documentation and Testing with RSwag'''&lt;br /&gt;
&lt;br /&gt;
Goal: Generate API documentation and test all endpoints.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get 'Retrieve notifications' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      response '200', 'success' do&lt;br /&gt;
        schema type: :array, items: { type: :object, properties: { id: { type: :integer }, subject: { type: :string } } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    post 'Create a notification' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: 'date' },&lt;br /&gt;
          is_active: { type: :boolean }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject description expiration_date]&lt;br /&gt;
      }&lt;br /&gt;
      response '201', 'created' do&lt;br /&gt;
        let(:notification) { { subject: 'Test', description: 'Test notification', expiration_date: '2024-12-31', is_active: true } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160685</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160685"/>
		<updated>2024-12-04T04:55:18Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* Design Pattern */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== New Files ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Model for Notification (models/notification.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/models/notification.rb Commit]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class Notification &amp;lt; ApplicationRecord&lt;br /&gt;
  # Associations&lt;br /&gt;
  belongs_to :course, foreign_key: :course_name, primary_key: :name&lt;br /&gt;
  belongs_to :user&lt;br /&gt;
  # Validations&lt;br /&gt;
  validates :subject, presence: true, length: { maximum: 255 }&lt;br /&gt;
  validates :description, presence: true&lt;br /&gt;
  validates :expiration_date, presence: true&lt;br /&gt;
  validate :expiration_date_cannot_be_in_the_past&lt;br /&gt;
  # Scopes&lt;br /&gt;
  scope :active, -&amp;gt; { where(active_flag: true) }&lt;br /&gt;
  scope :expired, -&amp;gt; { where('expiration_date &amp;lt; ?', Date.today) }&lt;br /&gt;
  scope :unread_by, -&amp;gt;(user) {&lt;br /&gt;
    joins(:course).where(courses: { id: user.assignments.pluck(:course_id) }).where(active_flag: true)&lt;br /&gt;
  }&lt;br /&gt;
  # Custom Validation for Expiration Date&lt;br /&gt;
  def expiration_date_cannot_be_in_the_past&lt;br /&gt;
    if expiration_date.present? &amp;amp;&amp;amp; expiration_date &amp;lt; Date.today&lt;br /&gt;
      errors.add(:expiration_date, &amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; 2. Controller for Notification (controllers/notification_controller.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/controllers/api/v1/notifications_controller.rb Commit]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class Api::V1::NotificationsController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
  before_action :set_notification, only: %i[show update destroy]&lt;br /&gt;
  # GET /notifications&lt;br /&gt;
  def index&lt;br /&gt;
    if current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      @notifications = Notification.where(user_id: current_user.id)&lt;br /&gt;
    elsif current_user_has_student_privileges?&lt;br /&gt;
      course_names = current_user.courses.pluck(:name)&lt;br /&gt;
      @notifications = Notification.where(course_name: course_names, active_flag: true)&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Access denied' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: @notifications&lt;br /&gt;
  end&lt;br /&gt;
  # GET /notifications/:id&lt;br /&gt;
  def show&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      render json: @notification&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You do not have access to this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # POST /notifications&lt;br /&gt;
  def create&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to create notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end &lt;br /&gt;
    @notification = Notification.new(notification_params)&lt;br /&gt;
    @notification.user_id = current_user.id&lt;br /&gt;
  &lt;br /&gt;
    if @notification.save&lt;br /&gt;
      render json: @notification, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH/PUT /notifications/:id&lt;br /&gt;
  def update&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to update notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.update(notification_params)&lt;br /&gt;
      render json: @notification, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # DELETE /notifications/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to delete notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.destroy&lt;br /&gt;
      render json: { message: 'Notification deleted successfully.' }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Failed to delete the notification.' }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH /notifications/:id/toggle_active&lt;br /&gt;
  def toggle_notification_visibility&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      @notification.update(active_flag: !@notification.active_flag)&lt;br /&gt;
      render json: { message: 'Notification visibility toggled successfully.', notification: @notification }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You are not authorized to toggle this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_notification&lt;br /&gt;
    @notification = Notification.find(params[:id])&lt;br /&gt;
  rescue ActiveRecord::RecordNotFound&lt;br /&gt;
    render json: { error: 'Notification not found.' }, status: :not_found&lt;br /&gt;
  end&lt;br /&gt;
  # Define strong parameters for notification creation/update&lt;br /&gt;
  def notification_params&lt;br /&gt;
    params.require(:notification).permit(:course_name, :subject, :description, :expiration_date, :active_flag)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method to check if a notification is accessible to the current user&lt;br /&gt;
  def notification_accessible?(notification)&lt;br /&gt;
    # Instructors and TAs can access their own notifications&lt;br /&gt;
    return true if notification.user_id == current_user.id&lt;br /&gt;
    # Students can access notifications for their courses&lt;br /&gt;
    return true if current_user_has_student_privileges? &amp;amp;&amp;amp;&lt;br /&gt;
                   current_user.courses.exists?(name: notification.course_name)&lt;br /&gt;
    false&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Following are the some of the SOLID principles with how they will be applied to the back-end development:&amp;lt;/b&amp;gt;&lt;br /&gt;
* Single Responsibility : Controllers handle HTTP requests, models handle data, and service objects handle business logic (e.g., sending notifications).&lt;br /&gt;
* Open/Closed : Extend functionality (e.g., new notification types or filters) by adding new classes or methods without modifying existing code.&lt;br /&gt;
* Interface Segregation : Create small, role-specific interfaces (e.g., policies for TAs, students, instructors) and separate service objects for different types of notifications.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
This section outlines the comprehensive testing approach for the Notifications feature to ensure it meets functional and non-functional requirements. The strategy includes detailed test cases for models, controllers, role-based access, and error handling, leveraging RSpec for testing and RSwag for API documentation.&lt;br /&gt;
&lt;br /&gt;
'''1. Unit Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure that the Notification model functions as expected by validating its attributes, associations, and methods.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
* Validations:&lt;br /&gt;
** Presence validation for subject, description, expiration_date, course_id, and user_id.&lt;br /&gt;
** Length constraints on subject and description.&lt;br /&gt;
** Format validation for expiration_date.&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :user and belongs_to :course associations are correctly established.&lt;br /&gt;
** Notifications have appropriate relationships with Course and User models.&lt;br /&gt;
&lt;br /&gt;
* Custom Methods and Scopes:&lt;br /&gt;
** active_notifications: Ensure only active notifications are returned.&lt;br /&gt;
** unread_notifications: Validate that unread notifications are fetched correctly.&lt;br /&gt;
&lt;br /&gt;
* Edge Cases:&lt;br /&gt;
** Notifications with an expired expiration_date should not appear in the active notifications list.&lt;br /&gt;
** Handling invalid foreign keys for user_id and course_id.&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe Notification, type: :model do&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it { should validate_presence_of(:subject) }&lt;br /&gt;
    it { should validate_presence_of(:description) }&lt;br /&gt;
    it { should validate_presence_of(:expiration_date) }&lt;br /&gt;
    it { should validate_length_of(:subject).is_at_most(100) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it { should belong_to(:user) }&lt;br /&gt;
    it { should belong_to(:course) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    let!(:active_notification) { create(:notification, is_active: true) }&lt;br /&gt;
    let!(:expired_notification) { create(:notification, expiration_date: Date.yesterday) }&lt;br /&gt;
    it 'returns active notifications' do&lt;br /&gt;
      expect(Notification.active_notifications).to include(active_notification)&lt;br /&gt;
      expect(Notification.active_notifications).not_to include(expired_notification)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Controller Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Test all CRUD operations for the Notifications controller to ensure endpoints function as expected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Index Action:&lt;br /&gt;
** Ensure all notifications for a given user are returned.&lt;br /&gt;
** Verify that unauthorized users cannot access the endpoint.&lt;br /&gt;
** Test paginated responses if applicable.&lt;br /&gt;
* Show Action:&lt;br /&gt;
** Ensure notifications can be retrieved by id.&lt;br /&gt;
** Handle cases where id is invalid or unauthorized.&lt;br /&gt;
* Create Action:&lt;br /&gt;
** Validate successful creation of notifications with proper attributes.&lt;br /&gt;
** Handle validation failures and unauthorized access.&lt;br /&gt;
* Update Action:&lt;br /&gt;
** Test updates to notification attributes.&lt;br /&gt;
** Ensure unauthorized users cannot perform updates.&lt;br /&gt;
* Delete Action:&lt;br /&gt;
** Verify notifications are deleted successfully.&lt;br /&gt;
** Test behavior when id is invalid or unauthorized.&lt;br /&gt;
&lt;br /&gt;
 require 'rails_helper'&lt;br /&gt;
 RSpec.describe Api::V1::NotificationsController, type: :controller do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let(:notification) { create(:notification) }&lt;br /&gt;
  describe 'GET #index' do&lt;br /&gt;
    before { sign_in admin }&lt;br /&gt;
    it 'returns notifications for the current user' do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:ok)&lt;br /&gt;
      expect(json_response).to include(notification)&lt;br /&gt;
    end&lt;br /&gt;
    it 'denies access to unauthorized users' do&lt;br /&gt;
      sign_out admin&lt;br /&gt;
      sign_in student&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:forbidden)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  describe 'POST #create' do&lt;br /&gt;
    context 'with valid attributes' do&lt;br /&gt;
      it 'creates a new notification' do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { notification: attributes_for(:notification) }&lt;br /&gt;
        }.to change(Notification, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'with invalid attributes' do&lt;br /&gt;
      it 'returns validation errors' do&lt;br /&gt;
        post :create, params: { notification: { subject: '' } }&lt;br /&gt;
        expect(response).to have_http_status(:unprocessable_entity)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''3. Integration Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure seamless interaction between models, controllers, and role-based access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Role-Based Access:&lt;br /&gt;
** Verify only authorized roles (e.g., Admin, Instructor) can manage notifications.&lt;br /&gt;
** Ensure students can only view notifications for their enrolled courses.&lt;br /&gt;
* Full CRUD Workflow:&lt;br /&gt;
** Test end-to-end creation, updating, and deletion of notifications.&lt;br /&gt;
* Error Scenarios:&lt;br /&gt;
** Handle cases where a notification is created for a non-existent course or user.&lt;br /&gt;
** Verify appropriate error messages for unauthorized actions.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications Integration', type: :request do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let!(:notification) { create(:notification, user: admin) }&lt;br /&gt;
  it 'allows admins to create notifications' do&lt;br /&gt;
    sign_in admin&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:created)&lt;br /&gt;
  end&lt;br /&gt;
  it 'prevents students from creating notifications' do&lt;br /&gt;
    sign_in student&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:forbidden)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''4. API Documentation and Testing with RSwag'''&lt;br /&gt;
&lt;br /&gt;
Goal: Generate API documentation and test all endpoints.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get 'Retrieve notifications' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      response '200', 'success' do&lt;br /&gt;
        schema type: :array, items: { type: :object, properties: { id: { type: :integer }, subject: { type: :string } } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    post 'Create a notification' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: 'date' },&lt;br /&gt;
          is_active: { type: :boolean }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject description expiration_date]&lt;br /&gt;
      }&lt;br /&gt;
      response '201', 'created' do&lt;br /&gt;
        let(:notification) { { subject: 'Test', description: 'Test notification', expiration_date: '2024-12-31', is_active: true } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160683</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160683"/>
		<updated>2024-12-04T04:53:38Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* New Files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== New Files ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Model for Notification (models/notification.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/models/notification.rb Commit]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class Notification &amp;lt; ApplicationRecord&lt;br /&gt;
  # Associations&lt;br /&gt;
  belongs_to :course, foreign_key: :course_name, primary_key: :name&lt;br /&gt;
  belongs_to :user&lt;br /&gt;
  # Validations&lt;br /&gt;
  validates :subject, presence: true, length: { maximum: 255 }&lt;br /&gt;
  validates :description, presence: true&lt;br /&gt;
  validates :expiration_date, presence: true&lt;br /&gt;
  validate :expiration_date_cannot_be_in_the_past&lt;br /&gt;
  # Scopes&lt;br /&gt;
  scope :active, -&amp;gt; { where(active_flag: true) }&lt;br /&gt;
  scope :expired, -&amp;gt; { where('expiration_date &amp;lt; ?', Date.today) }&lt;br /&gt;
  scope :unread_by, -&amp;gt;(user) {&lt;br /&gt;
    joins(:course).where(courses: { id: user.assignments.pluck(:course_id) }).where(active_flag: true)&lt;br /&gt;
  }&lt;br /&gt;
  # Custom Validation for Expiration Date&lt;br /&gt;
  def expiration_date_cannot_be_in_the_past&lt;br /&gt;
    if expiration_date.present? &amp;amp;&amp;amp; expiration_date &amp;lt; Date.today&lt;br /&gt;
      errors.add(:expiration_date, &amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; 2. Controller for Notification (controllers/notification_controller.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/controllers/api/v1/notifications_controller.rb Commit]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class Api::V1::NotificationsController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
  before_action :set_notification, only: %i[show update destroy]&lt;br /&gt;
  # GET /notifications&lt;br /&gt;
  def index&lt;br /&gt;
    if current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      @notifications = Notification.where(user_id: current_user.id)&lt;br /&gt;
    elsif current_user_has_student_privileges?&lt;br /&gt;
      course_names = current_user.courses.pluck(:name)&lt;br /&gt;
      @notifications = Notification.where(course_name: course_names, active_flag: true)&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Access denied' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: @notifications&lt;br /&gt;
  end&lt;br /&gt;
  # GET /notifications/:id&lt;br /&gt;
  def show&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      render json: @notification&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You do not have access to this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # POST /notifications&lt;br /&gt;
  def create&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to create notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end &lt;br /&gt;
    @notification = Notification.new(notification_params)&lt;br /&gt;
    @notification.user_id = current_user.id&lt;br /&gt;
  &lt;br /&gt;
    if @notification.save&lt;br /&gt;
      render json: @notification, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH/PUT /notifications/:id&lt;br /&gt;
  def update&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to update notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.update(notification_params)&lt;br /&gt;
      render json: @notification, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # DELETE /notifications/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to delete notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.destroy&lt;br /&gt;
      render json: { message: 'Notification deleted successfully.' }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Failed to delete the notification.' }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH /notifications/:id/toggle_active&lt;br /&gt;
  def toggle_notification_visibility&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      @notification.update(active_flag: !@notification.active_flag)&lt;br /&gt;
      render json: { message: 'Notification visibility toggled successfully.', notification: @notification }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You are not authorized to toggle this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_notification&lt;br /&gt;
    @notification = Notification.find(params[:id])&lt;br /&gt;
  rescue ActiveRecord::RecordNotFound&lt;br /&gt;
    render json: { error: 'Notification not found.' }, status: :not_found&lt;br /&gt;
  end&lt;br /&gt;
  # Define strong parameters for notification creation/update&lt;br /&gt;
  def notification_params&lt;br /&gt;
    params.require(:notification).permit(:course_name, :subject, :description, :expiration_date, :active_flag)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method to check if a notification is accessible to the current user&lt;br /&gt;
  def notification_accessible?(notification)&lt;br /&gt;
    # Instructors and TAs can access their own notifications&lt;br /&gt;
    return true if notification.user_id == current_user.id&lt;br /&gt;
    # Students can access notifications for their courses&lt;br /&gt;
    return true if current_user_has_student_privileges? &amp;amp;&amp;amp;&lt;br /&gt;
                   current_user.courses.exists?(name: notification.course_name)&lt;br /&gt;
    false&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Singleton Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Managing a global notification scheduler or manager, ensuring that only one instance exists.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Singleton Pattern ensures that there is only one centralized manager for handling notification-related tasks, such as scheduling or batch operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;4. Chain of Responsibility Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Modularizing the validation logic for notifications (e.g., checking permissions, validating expiration dates, ensuring uniqueness).&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Chain of Responsibility Pattern allows you to break down validation or processing logic into discrete steps, improving code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Following are the some of the SOLID principles with how they will be applied to the back-end development:&amp;lt;/b&amp;gt;&lt;br /&gt;
* Single Responsibility : Controllers handle HTTP requests, models handle data, and service objects handle business logic (e.g., sending notifications).&lt;br /&gt;
* Open/Closed : Extend functionality (e.g., new notification types or filters) by adding new classes or methods without modifying existing code.&lt;br /&gt;
* Interface Segregation : Create small, role-specific interfaces (e.g., policies for TAs, students, instructors) and separate service objects for different types of notifications.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
This section outlines the comprehensive testing approach for the Notifications feature to ensure it meets functional and non-functional requirements. The strategy includes detailed test cases for models, controllers, role-based access, and error handling, leveraging RSpec for testing and RSwag for API documentation.&lt;br /&gt;
&lt;br /&gt;
'''1. Unit Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure that the Notification model functions as expected by validating its attributes, associations, and methods.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
* Validations:&lt;br /&gt;
** Presence validation for subject, description, expiration_date, course_id, and user_id.&lt;br /&gt;
** Length constraints on subject and description.&lt;br /&gt;
** Format validation for expiration_date.&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :user and belongs_to :course associations are correctly established.&lt;br /&gt;
** Notifications have appropriate relationships with Course and User models.&lt;br /&gt;
&lt;br /&gt;
* Custom Methods and Scopes:&lt;br /&gt;
** active_notifications: Ensure only active notifications are returned.&lt;br /&gt;
** unread_notifications: Validate that unread notifications are fetched correctly.&lt;br /&gt;
&lt;br /&gt;
* Edge Cases:&lt;br /&gt;
** Notifications with an expired expiration_date should not appear in the active notifications list.&lt;br /&gt;
** Handling invalid foreign keys for user_id and course_id.&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe Notification, type: :model do&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it { should validate_presence_of(:subject) }&lt;br /&gt;
    it { should validate_presence_of(:description) }&lt;br /&gt;
    it { should validate_presence_of(:expiration_date) }&lt;br /&gt;
    it { should validate_length_of(:subject).is_at_most(100) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it { should belong_to(:user) }&lt;br /&gt;
    it { should belong_to(:course) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    let!(:active_notification) { create(:notification, is_active: true) }&lt;br /&gt;
    let!(:expired_notification) { create(:notification, expiration_date: Date.yesterday) }&lt;br /&gt;
    it 'returns active notifications' do&lt;br /&gt;
      expect(Notification.active_notifications).to include(active_notification)&lt;br /&gt;
      expect(Notification.active_notifications).not_to include(expired_notification)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Controller Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Test all CRUD operations for the Notifications controller to ensure endpoints function as expected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Index Action:&lt;br /&gt;
** Ensure all notifications for a given user are returned.&lt;br /&gt;
** Verify that unauthorized users cannot access the endpoint.&lt;br /&gt;
** Test paginated responses if applicable.&lt;br /&gt;
* Show Action:&lt;br /&gt;
** Ensure notifications can be retrieved by id.&lt;br /&gt;
** Handle cases where id is invalid or unauthorized.&lt;br /&gt;
* Create Action:&lt;br /&gt;
** Validate successful creation of notifications with proper attributes.&lt;br /&gt;
** Handle validation failures and unauthorized access.&lt;br /&gt;
* Update Action:&lt;br /&gt;
** Test updates to notification attributes.&lt;br /&gt;
** Ensure unauthorized users cannot perform updates.&lt;br /&gt;
* Delete Action:&lt;br /&gt;
** Verify notifications are deleted successfully.&lt;br /&gt;
** Test behavior when id is invalid or unauthorized.&lt;br /&gt;
&lt;br /&gt;
 require 'rails_helper'&lt;br /&gt;
 RSpec.describe Api::V1::NotificationsController, type: :controller do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let(:notification) { create(:notification) }&lt;br /&gt;
  describe 'GET #index' do&lt;br /&gt;
    before { sign_in admin }&lt;br /&gt;
    it 'returns notifications for the current user' do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:ok)&lt;br /&gt;
      expect(json_response).to include(notification)&lt;br /&gt;
    end&lt;br /&gt;
    it 'denies access to unauthorized users' do&lt;br /&gt;
      sign_out admin&lt;br /&gt;
      sign_in student&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:forbidden)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  describe 'POST #create' do&lt;br /&gt;
    context 'with valid attributes' do&lt;br /&gt;
      it 'creates a new notification' do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { notification: attributes_for(:notification) }&lt;br /&gt;
        }.to change(Notification, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'with invalid attributes' do&lt;br /&gt;
      it 'returns validation errors' do&lt;br /&gt;
        post :create, params: { notification: { subject: '' } }&lt;br /&gt;
        expect(response).to have_http_status(:unprocessable_entity)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''3. Integration Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure seamless interaction between models, controllers, and role-based access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Role-Based Access:&lt;br /&gt;
** Verify only authorized roles (e.g., Admin, Instructor) can manage notifications.&lt;br /&gt;
** Ensure students can only view notifications for their enrolled courses.&lt;br /&gt;
* Full CRUD Workflow:&lt;br /&gt;
** Test end-to-end creation, updating, and deletion of notifications.&lt;br /&gt;
* Error Scenarios:&lt;br /&gt;
** Handle cases where a notification is created for a non-existent course or user.&lt;br /&gt;
** Verify appropriate error messages for unauthorized actions.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications Integration', type: :request do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let!(:notification) { create(:notification, user: admin) }&lt;br /&gt;
  it 'allows admins to create notifications' do&lt;br /&gt;
    sign_in admin&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:created)&lt;br /&gt;
  end&lt;br /&gt;
  it 'prevents students from creating notifications' do&lt;br /&gt;
    sign_in student&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:forbidden)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''4. API Documentation and Testing with RSwag'''&lt;br /&gt;
&lt;br /&gt;
Goal: Generate API documentation and test all endpoints.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get 'Retrieve notifications' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      response '200', 'success' do&lt;br /&gt;
        schema type: :array, items: { type: :object, properties: { id: { type: :integer }, subject: { type: :string } } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    post 'Create a notification' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: 'date' },&lt;br /&gt;
          is_active: { type: :boolean }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject description expiration_date]&lt;br /&gt;
      }&lt;br /&gt;
      response '201', 'created' do&lt;br /&gt;
        let(:notification) { { subject: 'Test', description: 'Test notification', expiration_date: '2024-12-31', is_active: true } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160680</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160680"/>
		<updated>2024-12-04T04:52:25Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* New Files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== New Files ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Model for Notification (models/notification.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;a href=https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/models/notification.rb&amp;gt;Commit &amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class Notification &amp;lt; ApplicationRecord&lt;br /&gt;
  # Associations&lt;br /&gt;
  belongs_to :course, foreign_key: :course_name, primary_key: :name&lt;br /&gt;
  belongs_to :user&lt;br /&gt;
  # Validations&lt;br /&gt;
  validates :subject, presence: true, length: { maximum: 255 }&lt;br /&gt;
  validates :description, presence: true&lt;br /&gt;
  validates :expiration_date, presence: true&lt;br /&gt;
  validate :expiration_date_cannot_be_in_the_past&lt;br /&gt;
  # Scopes&lt;br /&gt;
  scope :active, -&amp;gt; { where(active_flag: true) }&lt;br /&gt;
  scope :expired, -&amp;gt; { where('expiration_date &amp;lt; ?', Date.today) }&lt;br /&gt;
  scope :unread_by, -&amp;gt;(user) {&lt;br /&gt;
    joins(:course).where(courses: { id: user.assignments.pluck(:course_id) }).where(active_flag: true)&lt;br /&gt;
  }&lt;br /&gt;
  # Custom Validation for Expiration Date&lt;br /&gt;
  def expiration_date_cannot_be_in_the_past&lt;br /&gt;
    if expiration_date.present? &amp;amp;&amp;amp; expiration_date &amp;lt; Date.today&lt;br /&gt;
      errors.add(:expiration_date, &amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; 2. Controller for Notification (controllers/notification_controller.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;a href=https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/controllers/api/v1/notifications_controller.rb&amp;gt;Commit&amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class Api::V1::NotificationsController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
  before_action :set_notification, only: %i[show update destroy]&lt;br /&gt;
  # GET /notifications&lt;br /&gt;
  def index&lt;br /&gt;
    if current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      @notifications = Notification.where(user_id: current_user.id)&lt;br /&gt;
    elsif current_user_has_student_privileges?&lt;br /&gt;
      course_names = current_user.courses.pluck(:name)&lt;br /&gt;
      @notifications = Notification.where(course_name: course_names, active_flag: true)&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Access denied' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: @notifications&lt;br /&gt;
  end&lt;br /&gt;
  # GET /notifications/:id&lt;br /&gt;
  def show&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      render json: @notification&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You do not have access to this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # POST /notifications&lt;br /&gt;
  def create&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to create notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end &lt;br /&gt;
    @notification = Notification.new(notification_params)&lt;br /&gt;
    @notification.user_id = current_user.id&lt;br /&gt;
  &lt;br /&gt;
    if @notification.save&lt;br /&gt;
      render json: @notification, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH/PUT /notifications/:id&lt;br /&gt;
  def update&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to update notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.update(notification_params)&lt;br /&gt;
      render json: @notification, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # DELETE /notifications/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to delete notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.destroy&lt;br /&gt;
      render json: { message: 'Notification deleted successfully.' }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Failed to delete the notification.' }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH /notifications/:id/toggle_active&lt;br /&gt;
  def toggle_notification_visibility&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      @notification.update(active_flag: !@notification.active_flag)&lt;br /&gt;
      render json: { message: 'Notification visibility toggled successfully.', notification: @notification }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You are not authorized to toggle this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_notification&lt;br /&gt;
    @notification = Notification.find(params[:id])&lt;br /&gt;
  rescue ActiveRecord::RecordNotFound&lt;br /&gt;
    render json: { error: 'Notification not found.' }, status: :not_found&lt;br /&gt;
  end&lt;br /&gt;
  # Define strong parameters for notification creation/update&lt;br /&gt;
  def notification_params&lt;br /&gt;
    params.require(:notification).permit(:course_name, :subject, :description, :expiration_date, :active_flag)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method to check if a notification is accessible to the current user&lt;br /&gt;
  def notification_accessible?(notification)&lt;br /&gt;
    # Instructors and TAs can access their own notifications&lt;br /&gt;
    return true if notification.user_id == current_user.id&lt;br /&gt;
    # Students can access notifications for their courses&lt;br /&gt;
    return true if current_user_has_student_privileges? &amp;amp;&amp;amp;&lt;br /&gt;
                   current_user.courses.exists?(name: notification.course_name)&lt;br /&gt;
    false&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Singleton Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Managing a global notification scheduler or manager, ensuring that only one instance exists.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Singleton Pattern ensures that there is only one centralized manager for handling notification-related tasks, such as scheduling or batch operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;4. Chain of Responsibility Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Modularizing the validation logic for notifications (e.g., checking permissions, validating expiration dates, ensuring uniqueness).&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Chain of Responsibility Pattern allows you to break down validation or processing logic into discrete steps, improving code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Following are the some of the SOLID principles with how they will be applied to the back-end development:&amp;lt;/b&amp;gt;&lt;br /&gt;
* Single Responsibility : Controllers handle HTTP requests, models handle data, and service objects handle business logic (e.g., sending notifications).&lt;br /&gt;
* Open/Closed : Extend functionality (e.g., new notification types or filters) by adding new classes or methods without modifying existing code.&lt;br /&gt;
* Interface Segregation : Create small, role-specific interfaces (e.g., policies for TAs, students, instructors) and separate service objects for different types of notifications.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
This section outlines the comprehensive testing approach for the Notifications feature to ensure it meets functional and non-functional requirements. The strategy includes detailed test cases for models, controllers, role-based access, and error handling, leveraging RSpec for testing and RSwag for API documentation.&lt;br /&gt;
&lt;br /&gt;
'''1. Unit Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure that the Notification model functions as expected by validating its attributes, associations, and methods.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
* Validations:&lt;br /&gt;
** Presence validation for subject, description, expiration_date, course_id, and user_id.&lt;br /&gt;
** Length constraints on subject and description.&lt;br /&gt;
** Format validation for expiration_date.&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :user and belongs_to :course associations are correctly established.&lt;br /&gt;
** Notifications have appropriate relationships with Course and User models.&lt;br /&gt;
&lt;br /&gt;
* Custom Methods and Scopes:&lt;br /&gt;
** active_notifications: Ensure only active notifications are returned.&lt;br /&gt;
** unread_notifications: Validate that unread notifications are fetched correctly.&lt;br /&gt;
&lt;br /&gt;
* Edge Cases:&lt;br /&gt;
** Notifications with an expired expiration_date should not appear in the active notifications list.&lt;br /&gt;
** Handling invalid foreign keys for user_id and course_id.&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe Notification, type: :model do&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it { should validate_presence_of(:subject) }&lt;br /&gt;
    it { should validate_presence_of(:description) }&lt;br /&gt;
    it { should validate_presence_of(:expiration_date) }&lt;br /&gt;
    it { should validate_length_of(:subject).is_at_most(100) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it { should belong_to(:user) }&lt;br /&gt;
    it { should belong_to(:course) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    let!(:active_notification) { create(:notification, is_active: true) }&lt;br /&gt;
    let!(:expired_notification) { create(:notification, expiration_date: Date.yesterday) }&lt;br /&gt;
    it 'returns active notifications' do&lt;br /&gt;
      expect(Notification.active_notifications).to include(active_notification)&lt;br /&gt;
      expect(Notification.active_notifications).not_to include(expired_notification)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Controller Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Test all CRUD operations for the Notifications controller to ensure endpoints function as expected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Index Action:&lt;br /&gt;
** Ensure all notifications for a given user are returned.&lt;br /&gt;
** Verify that unauthorized users cannot access the endpoint.&lt;br /&gt;
** Test paginated responses if applicable.&lt;br /&gt;
* Show Action:&lt;br /&gt;
** Ensure notifications can be retrieved by id.&lt;br /&gt;
** Handle cases where id is invalid or unauthorized.&lt;br /&gt;
* Create Action:&lt;br /&gt;
** Validate successful creation of notifications with proper attributes.&lt;br /&gt;
** Handle validation failures and unauthorized access.&lt;br /&gt;
* Update Action:&lt;br /&gt;
** Test updates to notification attributes.&lt;br /&gt;
** Ensure unauthorized users cannot perform updates.&lt;br /&gt;
* Delete Action:&lt;br /&gt;
** Verify notifications are deleted successfully.&lt;br /&gt;
** Test behavior when id is invalid or unauthorized.&lt;br /&gt;
&lt;br /&gt;
 require 'rails_helper'&lt;br /&gt;
 RSpec.describe Api::V1::NotificationsController, type: :controller do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let(:notification) { create(:notification) }&lt;br /&gt;
  describe 'GET #index' do&lt;br /&gt;
    before { sign_in admin }&lt;br /&gt;
    it 'returns notifications for the current user' do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:ok)&lt;br /&gt;
      expect(json_response).to include(notification)&lt;br /&gt;
    end&lt;br /&gt;
    it 'denies access to unauthorized users' do&lt;br /&gt;
      sign_out admin&lt;br /&gt;
      sign_in student&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:forbidden)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  describe 'POST #create' do&lt;br /&gt;
    context 'with valid attributes' do&lt;br /&gt;
      it 'creates a new notification' do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { notification: attributes_for(:notification) }&lt;br /&gt;
        }.to change(Notification, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'with invalid attributes' do&lt;br /&gt;
      it 'returns validation errors' do&lt;br /&gt;
        post :create, params: { notification: { subject: '' } }&lt;br /&gt;
        expect(response).to have_http_status(:unprocessable_entity)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''3. Integration Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure seamless interaction between models, controllers, and role-based access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Role-Based Access:&lt;br /&gt;
** Verify only authorized roles (e.g., Admin, Instructor) can manage notifications.&lt;br /&gt;
** Ensure students can only view notifications for their enrolled courses.&lt;br /&gt;
* Full CRUD Workflow:&lt;br /&gt;
** Test end-to-end creation, updating, and deletion of notifications.&lt;br /&gt;
* Error Scenarios:&lt;br /&gt;
** Handle cases where a notification is created for a non-existent course or user.&lt;br /&gt;
** Verify appropriate error messages for unauthorized actions.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications Integration', type: :request do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let!(:notification) { create(:notification, user: admin) }&lt;br /&gt;
  it 'allows admins to create notifications' do&lt;br /&gt;
    sign_in admin&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:created)&lt;br /&gt;
  end&lt;br /&gt;
  it 'prevents students from creating notifications' do&lt;br /&gt;
    sign_in student&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:forbidden)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''4. API Documentation and Testing with RSwag'''&lt;br /&gt;
&lt;br /&gt;
Goal: Generate API documentation and test all endpoints.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get 'Retrieve notifications' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      response '200', 'success' do&lt;br /&gt;
        schema type: :array, items: { type: :object, properties: { id: { type: :integer }, subject: { type: :string } } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    post 'Create a notification' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: 'date' },&lt;br /&gt;
          is_active: { type: :boolean }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject description expiration_date]&lt;br /&gt;
      }&lt;br /&gt;
      response '201', 'created' do&lt;br /&gt;
        let(:notification) { { subject: 'Test', description: 'Test notification', expiration_date: '2024-12-31', is_active: true } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160678</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160678"/>
		<updated>2024-12-04T04:51:14Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* New Files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== New Files ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Model for Notification (models/notification.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Commit: https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/models/notification.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class Notification &amp;lt; ApplicationRecord&lt;br /&gt;
  # Associations&lt;br /&gt;
  belongs_to :course, foreign_key: :course_name, primary_key: :name&lt;br /&gt;
  belongs_to :user&lt;br /&gt;
  # Validations&lt;br /&gt;
  validates :subject, presence: true, length: { maximum: 255 }&lt;br /&gt;
  validates :description, presence: true&lt;br /&gt;
  validates :expiration_date, presence: true&lt;br /&gt;
  validate :expiration_date_cannot_be_in_the_past&lt;br /&gt;
  # Scopes&lt;br /&gt;
  scope :active, -&amp;gt; { where(active_flag: true) }&lt;br /&gt;
  scope :expired, -&amp;gt; { where('expiration_date &amp;lt; ?', Date.today) }&lt;br /&gt;
  scope :unread_by, -&amp;gt;(user) {&lt;br /&gt;
    joins(:course).where(courses: { id: user.assignments.pluck(:course_id) }).where(active_flag: true)&lt;br /&gt;
  }&lt;br /&gt;
  # Custom Validation for Expiration Date&lt;br /&gt;
  def expiration_date_cannot_be_in_the_past&lt;br /&gt;
    if expiration_date.present? &amp;amp;&amp;amp; expiration_date &amp;lt; Date.today&lt;br /&gt;
      errors.add(:expiration_date, &amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; 2. Controller for Notification (controllers/notification_controller.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Commit: https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/controllers/api/v1/notifications_controller.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class Api::V1::NotificationsController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
  before_action :set_notification, only: %i[show update destroy]&lt;br /&gt;
  # GET /notifications&lt;br /&gt;
  def index&lt;br /&gt;
    if current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      @notifications = Notification.where(user_id: current_user.id)&lt;br /&gt;
    elsif current_user_has_student_privileges?&lt;br /&gt;
      course_names = current_user.courses.pluck(:name)&lt;br /&gt;
      @notifications = Notification.where(course_name: course_names, active_flag: true)&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Access denied' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    render json: @notifications&lt;br /&gt;
  end&lt;br /&gt;
  # GET /notifications/:id&lt;br /&gt;
  def show&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      render json: @notification&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You do not have access to this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # POST /notifications&lt;br /&gt;
  def create&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to create notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @notification = Notification.new(notification_params)&lt;br /&gt;
    @notification.user_id = current_user.id&lt;br /&gt;
  &lt;br /&gt;
    if @notification.save&lt;br /&gt;
      render json: @notification, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /notifications/:id&lt;br /&gt;
  def update&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to update notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.update(notification_params)&lt;br /&gt;
      render json: @notification, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # DELETE /notifications/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to delete notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
    if @notification.destroy&lt;br /&gt;
      render json: { message: 'Notification deleted successfully.' }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Failed to delete the notification.' }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  # PATCH /notifications/:id/toggle_active&lt;br /&gt;
  def toggle_notification_visibility&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      @notification.update(active_flag: !@notification.active_flag)&lt;br /&gt;
      render json: { message: 'Notification visibility toggled successfully.', notification: @notification }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You are not authorized to toggle this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_notification&lt;br /&gt;
    @notification = Notification.find(params[:id])&lt;br /&gt;
  rescue ActiveRecord::RecordNotFound&lt;br /&gt;
    render json: { error: 'Notification not found.' }, status: :not_found&lt;br /&gt;
  end&lt;br /&gt;
  # Define strong parameters for notification creation/update&lt;br /&gt;
  def notification_params&lt;br /&gt;
    params.require(:notification).permit(:course_name, :subject, :description, :expiration_date, :active_flag)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method to check if a notification is accessible to the current user&lt;br /&gt;
  def notification_accessible?(notification)&lt;br /&gt;
    # Instructors and TAs can access their own notifications&lt;br /&gt;
    return true if notification.user_id == current_user.id&lt;br /&gt;
    # Students can access notifications for their courses&lt;br /&gt;
    return true if current_user_has_student_privileges? &amp;amp;&amp;amp;&lt;br /&gt;
                   current_user.courses.exists?(name: notification.course_name)&lt;br /&gt;
    false&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Singleton Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Managing a global notification scheduler or manager, ensuring that only one instance exists.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Singleton Pattern ensures that there is only one centralized manager for handling notification-related tasks, such as scheduling or batch operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;4. Chain of Responsibility Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Modularizing the validation logic for notifications (e.g., checking permissions, validating expiration dates, ensuring uniqueness).&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Chain of Responsibility Pattern allows you to break down validation or processing logic into discrete steps, improving code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Following are the some of the SOLID principles with how they will be applied to the back-end development:&amp;lt;/b&amp;gt;&lt;br /&gt;
* Single Responsibility : Controllers handle HTTP requests, models handle data, and service objects handle business logic (e.g., sending notifications).&lt;br /&gt;
* Open/Closed : Extend functionality (e.g., new notification types or filters) by adding new classes or methods without modifying existing code.&lt;br /&gt;
* Interface Segregation : Create small, role-specific interfaces (e.g., policies for TAs, students, instructors) and separate service objects for different types of notifications.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
This section outlines the comprehensive testing approach for the Notifications feature to ensure it meets functional and non-functional requirements. The strategy includes detailed test cases for models, controllers, role-based access, and error handling, leveraging RSpec for testing and RSwag for API documentation.&lt;br /&gt;
&lt;br /&gt;
'''1. Unit Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure that the Notification model functions as expected by validating its attributes, associations, and methods.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
* Validations:&lt;br /&gt;
** Presence validation for subject, description, expiration_date, course_id, and user_id.&lt;br /&gt;
** Length constraints on subject and description.&lt;br /&gt;
** Format validation for expiration_date.&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :user and belongs_to :course associations are correctly established.&lt;br /&gt;
** Notifications have appropriate relationships with Course and User models.&lt;br /&gt;
&lt;br /&gt;
* Custom Methods and Scopes:&lt;br /&gt;
** active_notifications: Ensure only active notifications are returned.&lt;br /&gt;
** unread_notifications: Validate that unread notifications are fetched correctly.&lt;br /&gt;
&lt;br /&gt;
* Edge Cases:&lt;br /&gt;
** Notifications with an expired expiration_date should not appear in the active notifications list.&lt;br /&gt;
** Handling invalid foreign keys for user_id and course_id.&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe Notification, type: :model do&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it { should validate_presence_of(:subject) }&lt;br /&gt;
    it { should validate_presence_of(:description) }&lt;br /&gt;
    it { should validate_presence_of(:expiration_date) }&lt;br /&gt;
    it { should validate_length_of(:subject).is_at_most(100) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it { should belong_to(:user) }&lt;br /&gt;
    it { should belong_to(:course) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    let!(:active_notification) { create(:notification, is_active: true) }&lt;br /&gt;
    let!(:expired_notification) { create(:notification, expiration_date: Date.yesterday) }&lt;br /&gt;
    it 'returns active notifications' do&lt;br /&gt;
      expect(Notification.active_notifications).to include(active_notification)&lt;br /&gt;
      expect(Notification.active_notifications).not_to include(expired_notification)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Controller Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Test all CRUD operations for the Notifications controller to ensure endpoints function as expected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Index Action:&lt;br /&gt;
** Ensure all notifications for a given user are returned.&lt;br /&gt;
** Verify that unauthorized users cannot access the endpoint.&lt;br /&gt;
** Test paginated responses if applicable.&lt;br /&gt;
* Show Action:&lt;br /&gt;
** Ensure notifications can be retrieved by id.&lt;br /&gt;
** Handle cases where id is invalid or unauthorized.&lt;br /&gt;
* Create Action:&lt;br /&gt;
** Validate successful creation of notifications with proper attributes.&lt;br /&gt;
** Handle validation failures and unauthorized access.&lt;br /&gt;
* Update Action:&lt;br /&gt;
** Test updates to notification attributes.&lt;br /&gt;
** Ensure unauthorized users cannot perform updates.&lt;br /&gt;
* Delete Action:&lt;br /&gt;
** Verify notifications are deleted successfully.&lt;br /&gt;
** Test behavior when id is invalid or unauthorized.&lt;br /&gt;
&lt;br /&gt;
 require 'rails_helper'&lt;br /&gt;
 RSpec.describe Api::V1::NotificationsController, type: :controller do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let(:notification) { create(:notification) }&lt;br /&gt;
  describe 'GET #index' do&lt;br /&gt;
    before { sign_in admin }&lt;br /&gt;
    it 'returns notifications for the current user' do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:ok)&lt;br /&gt;
      expect(json_response).to include(notification)&lt;br /&gt;
    end&lt;br /&gt;
    it 'denies access to unauthorized users' do&lt;br /&gt;
      sign_out admin&lt;br /&gt;
      sign_in student&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:forbidden)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  describe 'POST #create' do&lt;br /&gt;
    context 'with valid attributes' do&lt;br /&gt;
      it 'creates a new notification' do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { notification: attributes_for(:notification) }&lt;br /&gt;
        }.to change(Notification, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'with invalid attributes' do&lt;br /&gt;
      it 'returns validation errors' do&lt;br /&gt;
        post :create, params: { notification: { subject: '' } }&lt;br /&gt;
        expect(response).to have_http_status(:unprocessable_entity)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''3. Integration Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure seamless interaction between models, controllers, and role-based access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Role-Based Access:&lt;br /&gt;
** Verify only authorized roles (e.g., Admin, Instructor) can manage notifications.&lt;br /&gt;
** Ensure students can only view notifications for their enrolled courses.&lt;br /&gt;
* Full CRUD Workflow:&lt;br /&gt;
** Test end-to-end creation, updating, and deletion of notifications.&lt;br /&gt;
* Error Scenarios:&lt;br /&gt;
** Handle cases where a notification is created for a non-existent course or user.&lt;br /&gt;
** Verify appropriate error messages for unauthorized actions.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications Integration', type: :request do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let!(:notification) { create(:notification, user: admin) }&lt;br /&gt;
  it 'allows admins to create notifications' do&lt;br /&gt;
    sign_in admin&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:created)&lt;br /&gt;
  end&lt;br /&gt;
  it 'prevents students from creating notifications' do&lt;br /&gt;
    sign_in student&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:forbidden)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''4. API Documentation and Testing with RSwag'''&lt;br /&gt;
&lt;br /&gt;
Goal: Generate API documentation and test all endpoints.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get 'Retrieve notifications' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      response '200', 'success' do&lt;br /&gt;
        schema type: :array, items: { type: :object, properties: { id: { type: :integer }, subject: { type: :string } } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    post 'Create a notification' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: 'date' },&lt;br /&gt;
          is_active: { type: :boolean }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject description expiration_date]&lt;br /&gt;
      }&lt;br /&gt;
      response '201', 'created' do&lt;br /&gt;
        let(:notification) { { subject: 'Test', description: 'Test notification', expiration_date: '2024-12-31', is_active: true } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160677</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160677"/>
		<updated>2024-12-04T04:50:27Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* New Files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== New Files ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Model for Notification (models/notification.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Commit: https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/models/notification.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class Notification &amp;lt; ApplicationRecord&lt;br /&gt;
  # Associations&lt;br /&gt;
  belongs_to :course, foreign_key: :course_name, primary_key: :name&lt;br /&gt;
  belongs_to :user&lt;br /&gt;
  # Validations&lt;br /&gt;
  validates :subject, presence: true, length: { maximum: 255 }&lt;br /&gt;
  validates :description, presence: true&lt;br /&gt;
  validates :expiration_date, presence: true&lt;br /&gt;
  validate :expiration_date_cannot_be_in_the_past&lt;br /&gt;
  # Scopes&lt;br /&gt;
  scope :active, -&amp;gt; { where(active_flag: true) }&lt;br /&gt;
  scope :expired, -&amp;gt; { where('expiration_date &amp;lt; ?', Date.today) }&lt;br /&gt;
  scope :unread_by, -&amp;gt;(user) {&lt;br /&gt;
    joins(:course).where(courses: { id: user.assignments.pluck(:course_id) }).where(active_flag: true)&lt;br /&gt;
  }&lt;br /&gt;
  # Custom Validation for Expiration Date&lt;br /&gt;
  def expiration_date_cannot_be_in_the_past&lt;br /&gt;
    if expiration_date.present? &amp;amp;&amp;amp; expiration_date &amp;lt; Date.today&lt;br /&gt;
      errors.add(:expiration_date, &amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; 2. Controller for Notification (controllers/notification_controller.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Commit: https://github.com/SoubarnicaSuresh/reimplementation-back-end/blob/main/app/controllers/api/v1/notifications_controller.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class Api::V1::NotificationsController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_notification, only: %i[show update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /notifications&lt;br /&gt;
  def index&lt;br /&gt;
    if current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      @notifications = Notification.where(user_id: current_user.id)&lt;br /&gt;
    elsif current_user_has_student_privileges?&lt;br /&gt;
      course_names = current_user.courses.pluck(:name)&lt;br /&gt;
      @notifications = Notification.where(course_name: course_names, active_flag: true)&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Access denied' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    render json: @notifications&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /notifications/:id&lt;br /&gt;
  def show&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      render json: @notification&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You do not have access to this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /notifications&lt;br /&gt;
  def create&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to create notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @notification = Notification.new(notification_params)&lt;br /&gt;
    @notification.user_id = current_user.id&lt;br /&gt;
  &lt;br /&gt;
    if @notification.save&lt;br /&gt;
      render json: @notification, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /notifications/:id&lt;br /&gt;
  def update&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to update notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    if @notification.update(notification_params)&lt;br /&gt;
      render json: @notification, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  # DELETE /notifications/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to delete notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    if @notification.destroy&lt;br /&gt;
      render json: { message: 'Notification deleted successfully.' }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Failed to delete the notification.' }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  # PATCH /notifications/:id/toggle_active&lt;br /&gt;
  def toggle_notification_visibility&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      @notification.update(active_flag: !@notification.active_flag)&lt;br /&gt;
      render json: { message: 'Notification visibility toggled successfully.', notification: @notification }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You are not authorized to toggle this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_notification&lt;br /&gt;
    @notification = Notification.find(params[:id])&lt;br /&gt;
  rescue ActiveRecord::RecordNotFound&lt;br /&gt;
    render json: { error: 'Notification not found.' }, status: :not_found&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Define strong parameters for notification creation/update&lt;br /&gt;
  def notification_params&lt;br /&gt;
    params.require(:notification).permit(:course_name, :subject, :description, :expiration_date, :active_flag)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Helper method to check if a notification is accessible to the current user&lt;br /&gt;
  def notification_accessible?(notification)&lt;br /&gt;
    # Instructors and TAs can access their own notifications&lt;br /&gt;
    return true if notification.user_id == current_user.id&lt;br /&gt;
&lt;br /&gt;
    # Students can access notifications for their courses&lt;br /&gt;
    return true if current_user_has_student_privileges? &amp;amp;&amp;amp;&lt;br /&gt;
                   current_user.courses.exists?(name: notification.course_name)&lt;br /&gt;
&lt;br /&gt;
    false&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Singleton Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Managing a global notification scheduler or manager, ensuring that only one instance exists.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Singleton Pattern ensures that there is only one centralized manager for handling notification-related tasks, such as scheduling or batch operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;4. Chain of Responsibility Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Modularizing the validation logic for notifications (e.g., checking permissions, validating expiration dates, ensuring uniqueness).&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Chain of Responsibility Pattern allows you to break down validation or processing logic into discrete steps, improving code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Following are the some of the SOLID principles with how they will be applied to the back-end development:&amp;lt;/b&amp;gt;&lt;br /&gt;
* Single Responsibility : Controllers handle HTTP requests, models handle data, and service objects handle business logic (e.g., sending notifications).&lt;br /&gt;
* Open/Closed : Extend functionality (e.g., new notification types or filters) by adding new classes or methods without modifying existing code.&lt;br /&gt;
* Interface Segregation : Create small, role-specific interfaces (e.g., policies for TAs, students, instructors) and separate service objects for different types of notifications.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
This section outlines the comprehensive testing approach for the Notifications feature to ensure it meets functional and non-functional requirements. The strategy includes detailed test cases for models, controllers, role-based access, and error handling, leveraging RSpec for testing and RSwag for API documentation.&lt;br /&gt;
&lt;br /&gt;
'''1. Unit Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure that the Notification model functions as expected by validating its attributes, associations, and methods.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
* Validations:&lt;br /&gt;
** Presence validation for subject, description, expiration_date, course_id, and user_id.&lt;br /&gt;
** Length constraints on subject and description.&lt;br /&gt;
** Format validation for expiration_date.&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :user and belongs_to :course associations are correctly established.&lt;br /&gt;
** Notifications have appropriate relationships with Course and User models.&lt;br /&gt;
&lt;br /&gt;
* Custom Methods and Scopes:&lt;br /&gt;
** active_notifications: Ensure only active notifications are returned.&lt;br /&gt;
** unread_notifications: Validate that unread notifications are fetched correctly.&lt;br /&gt;
&lt;br /&gt;
* Edge Cases:&lt;br /&gt;
** Notifications with an expired expiration_date should not appear in the active notifications list.&lt;br /&gt;
** Handling invalid foreign keys for user_id and course_id.&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe Notification, type: :model do&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it { should validate_presence_of(:subject) }&lt;br /&gt;
    it { should validate_presence_of(:description) }&lt;br /&gt;
    it { should validate_presence_of(:expiration_date) }&lt;br /&gt;
    it { should validate_length_of(:subject).is_at_most(100) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it { should belong_to(:user) }&lt;br /&gt;
    it { should belong_to(:course) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    let!(:active_notification) { create(:notification, is_active: true) }&lt;br /&gt;
    let!(:expired_notification) { create(:notification, expiration_date: Date.yesterday) }&lt;br /&gt;
    it 'returns active notifications' do&lt;br /&gt;
      expect(Notification.active_notifications).to include(active_notification)&lt;br /&gt;
      expect(Notification.active_notifications).not_to include(expired_notification)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Controller Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Test all CRUD operations for the Notifications controller to ensure endpoints function as expected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Index Action:&lt;br /&gt;
** Ensure all notifications for a given user are returned.&lt;br /&gt;
** Verify that unauthorized users cannot access the endpoint.&lt;br /&gt;
** Test paginated responses if applicable.&lt;br /&gt;
* Show Action:&lt;br /&gt;
** Ensure notifications can be retrieved by id.&lt;br /&gt;
** Handle cases where id is invalid or unauthorized.&lt;br /&gt;
* Create Action:&lt;br /&gt;
** Validate successful creation of notifications with proper attributes.&lt;br /&gt;
** Handle validation failures and unauthorized access.&lt;br /&gt;
* Update Action:&lt;br /&gt;
** Test updates to notification attributes.&lt;br /&gt;
** Ensure unauthorized users cannot perform updates.&lt;br /&gt;
* Delete Action:&lt;br /&gt;
** Verify notifications are deleted successfully.&lt;br /&gt;
** Test behavior when id is invalid or unauthorized.&lt;br /&gt;
&lt;br /&gt;
 require 'rails_helper'&lt;br /&gt;
 RSpec.describe Api::V1::NotificationsController, type: :controller do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let(:notification) { create(:notification) }&lt;br /&gt;
  describe 'GET #index' do&lt;br /&gt;
    before { sign_in admin }&lt;br /&gt;
    it 'returns notifications for the current user' do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:ok)&lt;br /&gt;
      expect(json_response).to include(notification)&lt;br /&gt;
    end&lt;br /&gt;
    it 'denies access to unauthorized users' do&lt;br /&gt;
      sign_out admin&lt;br /&gt;
      sign_in student&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:forbidden)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  describe 'POST #create' do&lt;br /&gt;
    context 'with valid attributes' do&lt;br /&gt;
      it 'creates a new notification' do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { notification: attributes_for(:notification) }&lt;br /&gt;
        }.to change(Notification, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'with invalid attributes' do&lt;br /&gt;
      it 'returns validation errors' do&lt;br /&gt;
        post :create, params: { notification: { subject: '' } }&lt;br /&gt;
        expect(response).to have_http_status(:unprocessable_entity)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''3. Integration Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure seamless interaction between models, controllers, and role-based access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Role-Based Access:&lt;br /&gt;
** Verify only authorized roles (e.g., Admin, Instructor) can manage notifications.&lt;br /&gt;
** Ensure students can only view notifications for their enrolled courses.&lt;br /&gt;
* Full CRUD Workflow:&lt;br /&gt;
** Test end-to-end creation, updating, and deletion of notifications.&lt;br /&gt;
* Error Scenarios:&lt;br /&gt;
** Handle cases where a notification is created for a non-existent course or user.&lt;br /&gt;
** Verify appropriate error messages for unauthorized actions.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications Integration', type: :request do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let!(:notification) { create(:notification, user: admin) }&lt;br /&gt;
  it 'allows admins to create notifications' do&lt;br /&gt;
    sign_in admin&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:created)&lt;br /&gt;
  end&lt;br /&gt;
  it 'prevents students from creating notifications' do&lt;br /&gt;
    sign_in student&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:forbidden)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''4. API Documentation and Testing with RSwag'''&lt;br /&gt;
&lt;br /&gt;
Goal: Generate API documentation and test all endpoints.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get 'Retrieve notifications' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      response '200', 'success' do&lt;br /&gt;
        schema type: :array, items: { type: :object, properties: { id: { type: :integer }, subject: { type: :string } } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    post 'Create a notification' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: 'date' },&lt;br /&gt;
          is_active: { type: :boolean }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject description expiration_date]&lt;br /&gt;
      }&lt;br /&gt;
      response '201', 'created' do&lt;br /&gt;
        let(:notification) { { subject: 'Test', description: 'Test notification', expiration_date: '2024-12-31', is_active: true } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160673</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160673"/>
		<updated>2024-12-04T04:48:20Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* New Files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== New Files ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Model for Notification (models/notification.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class Notification &amp;lt; ApplicationRecord&lt;br /&gt;
  # Associations&lt;br /&gt;
  belongs_to :course, foreign_key: :course_name, primary_key: :name&lt;br /&gt;
  belongs_to :user&lt;br /&gt;
  # Validations&lt;br /&gt;
  validates :subject, presence: true, length: { maximum: 255 }&lt;br /&gt;
  validates :description, presence: true&lt;br /&gt;
  validates :expiration_date, presence: true&lt;br /&gt;
  validate :expiration_date_cannot_be_in_the_past&lt;br /&gt;
  # Scopes&lt;br /&gt;
  scope :active, -&amp;gt; { where(active_flag: true) }&lt;br /&gt;
  scope :expired, -&amp;gt; { where('expiration_date &amp;lt; ?', Date.today) }&lt;br /&gt;
  scope :unread_by, -&amp;gt;(user) {&lt;br /&gt;
    joins(:course).where(courses: { id: user.assignments.pluck(:course_id) }).where(active_flag: true)&lt;br /&gt;
  }&lt;br /&gt;
  # Custom Validation for Expiration Date&lt;br /&gt;
  def expiration_date_cannot_be_in_the_past&lt;br /&gt;
    if expiration_date.present? &amp;amp;&amp;amp; expiration_date &amp;lt; Date.today&lt;br /&gt;
      errors.add(:expiration_date, &amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; 2. Controller for Notification (controllers/notification_controller.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class Api::V1::NotificationsController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_notification, only: %i[show update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /notifications&lt;br /&gt;
  def index&lt;br /&gt;
    if current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      @notifications = Notification.where(user_id: current_user.id)&lt;br /&gt;
    elsif current_user_has_student_privileges?&lt;br /&gt;
      course_names = current_user.courses.pluck(:name)&lt;br /&gt;
      @notifications = Notification.where(course_name: course_names, active_flag: true)&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Access denied' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    render json: @notifications&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /notifications/:id&lt;br /&gt;
  def show&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      render json: @notification&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You do not have access to this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /notifications&lt;br /&gt;
  def create&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to create notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @notification = Notification.new(notification_params)&lt;br /&gt;
    @notification.user_id = current_user.id&lt;br /&gt;
  &lt;br /&gt;
    if @notification.save&lt;br /&gt;
      render json: @notification, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /notifications/:id&lt;br /&gt;
  def update&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to update notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    if @notification.update(notification_params)&lt;br /&gt;
      render json: @notification, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  # DELETE /notifications/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to delete notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    if @notification.destroy&lt;br /&gt;
      render json: { message: 'Notification deleted successfully.' }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Failed to delete the notification.' }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  # PATCH /notifications/:id/toggle_active&lt;br /&gt;
  def toggle_notification_visibility&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      @notification.update(active_flag: !@notification.active_flag)&lt;br /&gt;
      render json: { message: 'Notification visibility toggled successfully.', notification: @notification }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You are not authorized to toggle this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_notification&lt;br /&gt;
    @notification = Notification.find(params[:id])&lt;br /&gt;
  rescue ActiveRecord::RecordNotFound&lt;br /&gt;
    render json: { error: 'Notification not found.' }, status: :not_found&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Define strong parameters for notification creation/update&lt;br /&gt;
  def notification_params&lt;br /&gt;
    params.require(:notification).permit(:course_name, :subject, :description, :expiration_date, :active_flag)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Helper method to check if a notification is accessible to the current user&lt;br /&gt;
  def notification_accessible?(notification)&lt;br /&gt;
    # Instructors and TAs can access their own notifications&lt;br /&gt;
    return true if notification.user_id == current_user.id&lt;br /&gt;
&lt;br /&gt;
    # Students can access notifications for their courses&lt;br /&gt;
    return true if current_user_has_student_privileges? &amp;amp;&amp;amp;&lt;br /&gt;
                   current_user.courses.exists?(name: notification.course_name)&lt;br /&gt;
&lt;br /&gt;
    false&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Singleton Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Managing a global notification scheduler or manager, ensuring that only one instance exists.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Singleton Pattern ensures that there is only one centralized manager for handling notification-related tasks, such as scheduling or batch operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;4. Chain of Responsibility Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Modularizing the validation logic for notifications (e.g., checking permissions, validating expiration dates, ensuring uniqueness).&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Chain of Responsibility Pattern allows you to break down validation or processing logic into discrete steps, improving code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Following are the some of the SOLID principles with how they will be applied to the back-end development:&amp;lt;/b&amp;gt;&lt;br /&gt;
* Single Responsibility : Controllers handle HTTP requests, models handle data, and service objects handle business logic (e.g., sending notifications).&lt;br /&gt;
* Open/Closed : Extend functionality (e.g., new notification types or filters) by adding new classes or methods without modifying existing code.&lt;br /&gt;
* Interface Segregation : Create small, role-specific interfaces (e.g., policies for TAs, students, instructors) and separate service objects for different types of notifications.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
This section outlines the comprehensive testing approach for the Notifications feature to ensure it meets functional and non-functional requirements. The strategy includes detailed test cases for models, controllers, role-based access, and error handling, leveraging RSpec for testing and RSwag for API documentation.&lt;br /&gt;
&lt;br /&gt;
'''1. Unit Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure that the Notification model functions as expected by validating its attributes, associations, and methods.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
* Validations:&lt;br /&gt;
** Presence validation for subject, description, expiration_date, course_id, and user_id.&lt;br /&gt;
** Length constraints on subject and description.&lt;br /&gt;
** Format validation for expiration_date.&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :user and belongs_to :course associations are correctly established.&lt;br /&gt;
** Notifications have appropriate relationships with Course and User models.&lt;br /&gt;
&lt;br /&gt;
* Custom Methods and Scopes:&lt;br /&gt;
** active_notifications: Ensure only active notifications are returned.&lt;br /&gt;
** unread_notifications: Validate that unread notifications are fetched correctly.&lt;br /&gt;
&lt;br /&gt;
* Edge Cases:&lt;br /&gt;
** Notifications with an expired expiration_date should not appear in the active notifications list.&lt;br /&gt;
** Handling invalid foreign keys for user_id and course_id.&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe Notification, type: :model do&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it { should validate_presence_of(:subject) }&lt;br /&gt;
    it { should validate_presence_of(:description) }&lt;br /&gt;
    it { should validate_presence_of(:expiration_date) }&lt;br /&gt;
    it { should validate_length_of(:subject).is_at_most(100) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it { should belong_to(:user) }&lt;br /&gt;
    it { should belong_to(:course) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    let!(:active_notification) { create(:notification, is_active: true) }&lt;br /&gt;
    let!(:expired_notification) { create(:notification, expiration_date: Date.yesterday) }&lt;br /&gt;
    it 'returns active notifications' do&lt;br /&gt;
      expect(Notification.active_notifications).to include(active_notification)&lt;br /&gt;
      expect(Notification.active_notifications).not_to include(expired_notification)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Controller Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Test all CRUD operations for the Notifications controller to ensure endpoints function as expected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Index Action:&lt;br /&gt;
** Ensure all notifications for a given user are returned.&lt;br /&gt;
** Verify that unauthorized users cannot access the endpoint.&lt;br /&gt;
** Test paginated responses if applicable.&lt;br /&gt;
* Show Action:&lt;br /&gt;
** Ensure notifications can be retrieved by id.&lt;br /&gt;
** Handle cases where id is invalid or unauthorized.&lt;br /&gt;
* Create Action:&lt;br /&gt;
** Validate successful creation of notifications with proper attributes.&lt;br /&gt;
** Handle validation failures and unauthorized access.&lt;br /&gt;
* Update Action:&lt;br /&gt;
** Test updates to notification attributes.&lt;br /&gt;
** Ensure unauthorized users cannot perform updates.&lt;br /&gt;
* Delete Action:&lt;br /&gt;
** Verify notifications are deleted successfully.&lt;br /&gt;
** Test behavior when id is invalid or unauthorized.&lt;br /&gt;
&lt;br /&gt;
 require 'rails_helper'&lt;br /&gt;
 RSpec.describe Api::V1::NotificationsController, type: :controller do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let(:notification) { create(:notification) }&lt;br /&gt;
  describe 'GET #index' do&lt;br /&gt;
    before { sign_in admin }&lt;br /&gt;
    it 'returns notifications for the current user' do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:ok)&lt;br /&gt;
      expect(json_response).to include(notification)&lt;br /&gt;
    end&lt;br /&gt;
    it 'denies access to unauthorized users' do&lt;br /&gt;
      sign_out admin&lt;br /&gt;
      sign_in student&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:forbidden)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  describe 'POST #create' do&lt;br /&gt;
    context 'with valid attributes' do&lt;br /&gt;
      it 'creates a new notification' do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { notification: attributes_for(:notification) }&lt;br /&gt;
        }.to change(Notification, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'with invalid attributes' do&lt;br /&gt;
      it 'returns validation errors' do&lt;br /&gt;
        post :create, params: { notification: { subject: '' } }&lt;br /&gt;
        expect(response).to have_http_status(:unprocessable_entity)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''3. Integration Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure seamless interaction between models, controllers, and role-based access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Role-Based Access:&lt;br /&gt;
** Verify only authorized roles (e.g., Admin, Instructor) can manage notifications.&lt;br /&gt;
** Ensure students can only view notifications for their enrolled courses.&lt;br /&gt;
* Full CRUD Workflow:&lt;br /&gt;
** Test end-to-end creation, updating, and deletion of notifications.&lt;br /&gt;
* Error Scenarios:&lt;br /&gt;
** Handle cases where a notification is created for a non-existent course or user.&lt;br /&gt;
** Verify appropriate error messages for unauthorized actions.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications Integration', type: :request do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let!(:notification) { create(:notification, user: admin) }&lt;br /&gt;
  it 'allows admins to create notifications' do&lt;br /&gt;
    sign_in admin&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:created)&lt;br /&gt;
  end&lt;br /&gt;
  it 'prevents students from creating notifications' do&lt;br /&gt;
    sign_in student&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:forbidden)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''4. API Documentation and Testing with RSwag'''&lt;br /&gt;
&lt;br /&gt;
Goal: Generate API documentation and test all endpoints.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get 'Retrieve notifications' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      response '200', 'success' do&lt;br /&gt;
        schema type: :array, items: { type: :object, properties: { id: { type: :integer }, subject: { type: :string } } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    post 'Create a notification' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: 'date' },&lt;br /&gt;
          is_active: { type: :boolean }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject description expiration_date]&lt;br /&gt;
      }&lt;br /&gt;
      response '201', 'created' do&lt;br /&gt;
        let(:notification) { { subject: 'Test', description: 'Test notification', expiration_date: '2024-12-31', is_active: true } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160672</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160672"/>
		<updated>2024-12-04T04:46:27Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* New Files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== New Files ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Model for Notification (models/notification.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class Notification &amp;lt; ApplicationRecord&lt;br /&gt;
  # Associations&lt;br /&gt;
  belongs_to :course, foreign_key: :course_name, primary_key: :name&lt;br /&gt;
  belongs_to :user&lt;br /&gt;
  # Validations&lt;br /&gt;
  validates :subject, presence: true, length: { maximum: 255 }&lt;br /&gt;
  validates :description, presence: true&lt;br /&gt;
  validates :expiration_date, presence: true&lt;br /&gt;
  validate :expiration_date_cannot_be_in_the_past&lt;br /&gt;
  # Scopes&lt;br /&gt;
  scope :active, -&amp;gt; { where(active_flag: true) }&lt;br /&gt;
  scope :expired, -&amp;gt; { where('expiration_date &amp;lt; ?', Date.today) }&lt;br /&gt;
  scope :unread_by, -&amp;gt;(user) {&lt;br /&gt;
    joins(:course).where(courses: { id: user.assignments.pluck(:course_id) }).where(active_flag: true)&lt;br /&gt;
  }&lt;br /&gt;
  # Custom Validation for Expiration Date&lt;br /&gt;
  def expiration_date_cannot_be_in_the_past&lt;br /&gt;
    if expiration_date.present? &amp;amp;&amp;amp; expiration_date &amp;lt; Date.today&lt;br /&gt;
      errors.add(:expiration_date, &amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; 2. Controller for Notification (controllers/notification_controller.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class Api::V1::NotificationsController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_notification, only: %i[show update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /notifications&lt;br /&gt;
  def index&lt;br /&gt;
    if current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      @notifications = Notification.where(user_id: current_user.id)&lt;br /&gt;
    elsif current_user_has_student_privileges?&lt;br /&gt;
      course_names = current_user.courses.pluck(:name)&lt;br /&gt;
      @notifications = Notification.where(course_name: course_names, active_flag: true)&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Access denied' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    render json: @notifications&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /notifications/:id&lt;br /&gt;
  def show&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      render json: @notification&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You do not have access to this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /notifications&lt;br /&gt;
  def create&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to create notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @notification = Notification.new(notification_params)&lt;br /&gt;
    @notification.user_id = current_user.id&lt;br /&gt;
  &lt;br /&gt;
    if @notification.save&lt;br /&gt;
      render json: @notification, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /notifications/:id&lt;br /&gt;
  def update&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to update notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    if @notification.update(notification_params)&lt;br /&gt;
      render json: @notification, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  # DELETE /notifications/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to delete notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    if @notification.destroy&lt;br /&gt;
      render json: { message: 'Notification deleted successfully.' }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Failed to delete the notification.' }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  # PATCH /notifications/:id/toggle_active&lt;br /&gt;
  def toggle_notification_visibility&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      @notification.update(active_flag: !@notification.active_flag)&lt;br /&gt;
      render json: { message: 'Notification visibility toggled successfully.', notification: @notification }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You are not authorized to toggle this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_notification&lt;br /&gt;
    @notification = Notification.find(params[:id])&lt;br /&gt;
  rescue ActiveRecord::RecordNotFound&lt;br /&gt;
    render json: { error: 'Notification not found.' }, status: :not_found&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Define strong parameters for notification creation/update&lt;br /&gt;
  def notification_params&lt;br /&gt;
    params.require(:notification).permit(:course_name, :subject, :description, :expiration_date, :active_flag)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Helper method to check if a notification is accessible to the current user&lt;br /&gt;
  def notification_accessible?(notification)&lt;br /&gt;
    # Instructors and TAs can access their own notifications&lt;br /&gt;
    return true if notification.user_id == current_user.id&lt;br /&gt;
&lt;br /&gt;
    # Students can access notifications for their courses&lt;br /&gt;
    return true if current_user_has_student_privileges? &amp;amp;&amp;amp;&lt;br /&gt;
                   current_user.courses.exists?(name: notification.course_name)&lt;br /&gt;
&lt;br /&gt;
    false&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; 3. Spec for Controller (spec/requests/api/v1/notification_controller.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
require 'swagger_helper'&lt;br /&gt;
&lt;br /&gt;
RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  let(:user) { create(:user, name: 'test_user') }&lt;br /&gt;
  let(:course) { create(:course, name: 'Ruby 101', instructor_id: user.id, institution_id: 1) }&lt;br /&gt;
  let(:notification) { create(:notification, course: course, user: user, subject: 'Test Notification') }&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get('list notifications') do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
&lt;br /&gt;
      response(200, 'Success') do&lt;br /&gt;
        let!(:notifications) { create_list(:notification, 5, user: user, course: course) }&lt;br /&gt;
&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do |response|&lt;br /&gt;
          expect(JSON.parse(response.body).size).to eq(5)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    post('create notification') do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: :date },&lt;br /&gt;
          active_flag: { type: :boolean },&lt;br /&gt;
          course_id: { type: :integer }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject course_id]&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      response(201, 'Created') do&lt;br /&gt;
        let(:notification) { { subject: 'New Notification', description: 'Details', expiration_date: Date.today + 7, course_id: course.id } }&lt;br /&gt;
&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      response(422, 'Unprocessable Entity') do&lt;br /&gt;
        let(:notification) { { description: 'Details', expiration_date: Date.today + 7, course_id: course.id } }&lt;br /&gt;
&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/notifications/{id}' do&lt;br /&gt;
    parameter name: :id, in: :path, type: :integer, description: 'ID of the notification'&lt;br /&gt;
&lt;br /&gt;
    get('show notification') do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      response(200, 'Success') do&lt;br /&gt;
        let(:id) { notification.id }&lt;br /&gt;
&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      response(404, 'Not Found') do&lt;br /&gt;
        let(:id) { 'INVALID' }&lt;br /&gt;
&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    patch('update notification') do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: :date },&lt;br /&gt;
          active_flag: { type: :boolean }&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      response(200, 'Updated') do&lt;br /&gt;
        let(:id) { notification.id }&lt;br /&gt;
        let(:notification) { { subject: 'Updated Notification', active_flag: true } }&lt;br /&gt;
&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      response(404, 'Not Found') do&lt;br /&gt;
        let(:id) { 'INVALID' }&lt;br /&gt;
        let(:notification) { { subject: 'Updated Notification', active_flag: true } }&lt;br /&gt;
&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    delete('delete notification') do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
&lt;br /&gt;
      response(204, 'Deleted') do&lt;br /&gt;
        let(:id) { notification.id }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      response(404, 'Not Found') do&lt;br /&gt;
        let(:id) { 'INVALID' }&lt;br /&gt;
&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/notifications/{id}/toggle_active' do&lt;br /&gt;
    parameter name: :id, in: :path, type: :integer, description: 'ID of the notification'&lt;br /&gt;
&lt;br /&gt;
    patch('toggle notification visibility') do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
&lt;br /&gt;
      response(200, 'Visibility toggled') do&lt;br /&gt;
        let(:id) { notification.id }&lt;br /&gt;
&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      response(404, 'Not Found') do&lt;br /&gt;
        let(:id) { 'INVALID' }&lt;br /&gt;
&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; 4. Tests for Model (spec/models/notification_spec.rb)&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
&lt;br /&gt;
RSpec.describe Notification, type: :model do&lt;br /&gt;
  before(:each) do&lt;br /&gt;
    # Mock the course and user&lt;br /&gt;
    @course = instance_double(Course, name: &amp;quot;Ruby 101&amp;quot;)&lt;br /&gt;
    role = instance_double(Role, id: 1, name: &amp;quot;Student&amp;quot;)&lt;br /&gt;
    @user = instance_double(User, id: 1, name: &amp;quot;Test User&amp;quot;, email: &amp;quot;test@example.com&amp;quot;, role: role)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it 'is invalid without a subject' do&lt;br /&gt;
      notification = Notification.new(subject: nil)&lt;br /&gt;
      expect(notification).not_to be_valid&lt;br /&gt;
      expect(notification.errors[:subject]).to include(&amp;quot;can't be blank&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'is invalid without a description' do&lt;br /&gt;
      notification = Notification.new(description: nil)&lt;br /&gt;
      expect(notification).not_to be_valid&lt;br /&gt;
      expect(notification.errors[:description]).to include(&amp;quot;can't be blank&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'is invalid without an expiration_date' do&lt;br /&gt;
      notification = Notification.new(expiration_date: nil)&lt;br /&gt;
      expect(notification).not_to be_valid&lt;br /&gt;
      expect(notification.errors[:expiration_date]).to include(&amp;quot;can't be blank&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'is invalid if expiration_date is in the past' do&lt;br /&gt;
      notification = Notification.new(expiration_date: Date.yesterday)&lt;br /&gt;
      expect(notification).not_to be_valid&lt;br /&gt;
      expect(notification.errors[:expiration_date]).to include(&amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it 'belongs to a course' do&lt;br /&gt;
      # Mock the course association&lt;br /&gt;
      notification = Notification.new&lt;br /&gt;
      allow(notification).to receive(:course).and_return(@course)&lt;br /&gt;
&lt;br /&gt;
      # Test that the association returns the mocked course&lt;br /&gt;
      expect(notification.course).to eq(@course)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'belongs to a user' do&lt;br /&gt;
      # Mock the user association&lt;br /&gt;
      notification = Notification.new&lt;br /&gt;
      allow(notification).to receive(:user).and_return(@user)&lt;br /&gt;
&lt;br /&gt;
      # Test that the association returns the mocked user&lt;br /&gt;
      expect(notification.user).to eq(@user)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      @notification1 = instance_double(&lt;br /&gt;
        Notification,&lt;br /&gt;
        subject: &amp;quot;Active Notification&amp;quot;,&lt;br /&gt;
        expiration_date: Date.today + 3,&lt;br /&gt;
        active_flag: true,&lt;br /&gt;
        course_name: @course.name,&lt;br /&gt;
        user: @user&lt;br /&gt;
      )&lt;br /&gt;
&lt;br /&gt;
      @notification2 = instance_double(&lt;br /&gt;
        Notification,&lt;br /&gt;
        subject: &amp;quot;Expired Notification&amp;quot;,&lt;br /&gt;
        expiration_date: Date.yesterday,&lt;br /&gt;
        active_flag: true,&lt;br /&gt;
        course_name: @course.name,&lt;br /&gt;
        user: @user&lt;br /&gt;
      )&lt;br /&gt;
&lt;br /&gt;
      @notification3 = instance_double(&lt;br /&gt;
        Notification,&lt;br /&gt;
        subject: &amp;quot;Inactive Notification&amp;quot;,&lt;br /&gt;
        expiration_date: Date.today + 7,&lt;br /&gt;
        active_flag: false,&lt;br /&gt;
        course_name: @course.name,&lt;br /&gt;
        user: @user&lt;br /&gt;
      )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    describe '.active' do&lt;br /&gt;
      it 'returns notifications that are active' do&lt;br /&gt;
        allow(Notification).to receive(:active).and_return([@notification1])&lt;br /&gt;
        expect(Notification.active).to include(@notification1)&lt;br /&gt;
        expect(Notification.active).not_to include(@notification2, @notification3)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    describe '.expired' do&lt;br /&gt;
      it 'returns notifications that are expired' do&lt;br /&gt;
        allow(Notification).to receive(:expired).and_return([@notification2])&lt;br /&gt;
        expect(Notification.expired).to include(@notification2)&lt;br /&gt;
        expect(Notification.expired).not_to include(@notification1, @notification3)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    describe '.unread_by' do&lt;br /&gt;
      it 'returns notifications that are unread by the user' do&lt;br /&gt;
        allow(Notification).to receive(:unread_by).with(@user).and_return([@notification1])&lt;br /&gt;
        unread_notifications = Notification.unread_by(@user)&lt;br /&gt;
        expect(unread_notifications).to include(@notification1)&lt;br /&gt;
        expect(unread_notifications).not_to include(@notification2, @notification3)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Singleton Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Managing a global notification scheduler or manager, ensuring that only one instance exists.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Singleton Pattern ensures that there is only one centralized manager for handling notification-related tasks, such as scheduling or batch operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;4. Chain of Responsibility Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Modularizing the validation logic for notifications (e.g., checking permissions, validating expiration dates, ensuring uniqueness).&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Chain of Responsibility Pattern allows you to break down validation or processing logic into discrete steps, improving code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Following are the some of the SOLID principles with how they will be applied to the back-end development:&amp;lt;/b&amp;gt;&lt;br /&gt;
* Single Responsibility : Controllers handle HTTP requests, models handle data, and service objects handle business logic (e.g., sending notifications).&lt;br /&gt;
* Open/Closed : Extend functionality (e.g., new notification types or filters) by adding new classes or methods without modifying existing code.&lt;br /&gt;
* Interface Segregation : Create small, role-specific interfaces (e.g., policies for TAs, students, instructors) and separate service objects for different types of notifications.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
This section outlines the comprehensive testing approach for the Notifications feature to ensure it meets functional and non-functional requirements. The strategy includes detailed test cases for models, controllers, role-based access, and error handling, leveraging RSpec for testing and RSwag for API documentation.&lt;br /&gt;
&lt;br /&gt;
'''1. Unit Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure that the Notification model functions as expected by validating its attributes, associations, and methods.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
* Validations:&lt;br /&gt;
** Presence validation for subject, description, expiration_date, course_id, and user_id.&lt;br /&gt;
** Length constraints on subject and description.&lt;br /&gt;
** Format validation for expiration_date.&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :user and belongs_to :course associations are correctly established.&lt;br /&gt;
** Notifications have appropriate relationships with Course and User models.&lt;br /&gt;
&lt;br /&gt;
* Custom Methods and Scopes:&lt;br /&gt;
** active_notifications: Ensure only active notifications are returned.&lt;br /&gt;
** unread_notifications: Validate that unread notifications are fetched correctly.&lt;br /&gt;
&lt;br /&gt;
* Edge Cases:&lt;br /&gt;
** Notifications with an expired expiration_date should not appear in the active notifications list.&lt;br /&gt;
** Handling invalid foreign keys for user_id and course_id.&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe Notification, type: :model do&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it { should validate_presence_of(:subject) }&lt;br /&gt;
    it { should validate_presence_of(:description) }&lt;br /&gt;
    it { should validate_presence_of(:expiration_date) }&lt;br /&gt;
    it { should validate_length_of(:subject).is_at_most(100) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it { should belong_to(:user) }&lt;br /&gt;
    it { should belong_to(:course) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    let!(:active_notification) { create(:notification, is_active: true) }&lt;br /&gt;
    let!(:expired_notification) { create(:notification, expiration_date: Date.yesterday) }&lt;br /&gt;
    it 'returns active notifications' do&lt;br /&gt;
      expect(Notification.active_notifications).to include(active_notification)&lt;br /&gt;
      expect(Notification.active_notifications).not_to include(expired_notification)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Controller Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Test all CRUD operations for the Notifications controller to ensure endpoints function as expected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Index Action:&lt;br /&gt;
** Ensure all notifications for a given user are returned.&lt;br /&gt;
** Verify that unauthorized users cannot access the endpoint.&lt;br /&gt;
** Test paginated responses if applicable.&lt;br /&gt;
* Show Action:&lt;br /&gt;
** Ensure notifications can be retrieved by id.&lt;br /&gt;
** Handle cases where id is invalid or unauthorized.&lt;br /&gt;
* Create Action:&lt;br /&gt;
** Validate successful creation of notifications with proper attributes.&lt;br /&gt;
** Handle validation failures and unauthorized access.&lt;br /&gt;
* Update Action:&lt;br /&gt;
** Test updates to notification attributes.&lt;br /&gt;
** Ensure unauthorized users cannot perform updates.&lt;br /&gt;
* Delete Action:&lt;br /&gt;
** Verify notifications are deleted successfully.&lt;br /&gt;
** Test behavior when id is invalid or unauthorized.&lt;br /&gt;
&lt;br /&gt;
 require 'rails_helper'&lt;br /&gt;
 RSpec.describe Api::V1::NotificationsController, type: :controller do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let(:notification) { create(:notification) }&lt;br /&gt;
  describe 'GET #index' do&lt;br /&gt;
    before { sign_in admin }&lt;br /&gt;
    it 'returns notifications for the current user' do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:ok)&lt;br /&gt;
      expect(json_response).to include(notification)&lt;br /&gt;
    end&lt;br /&gt;
    it 'denies access to unauthorized users' do&lt;br /&gt;
      sign_out admin&lt;br /&gt;
      sign_in student&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:forbidden)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  describe 'POST #create' do&lt;br /&gt;
    context 'with valid attributes' do&lt;br /&gt;
      it 'creates a new notification' do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { notification: attributes_for(:notification) }&lt;br /&gt;
        }.to change(Notification, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'with invalid attributes' do&lt;br /&gt;
      it 'returns validation errors' do&lt;br /&gt;
        post :create, params: { notification: { subject: '' } }&lt;br /&gt;
        expect(response).to have_http_status(:unprocessable_entity)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''3. Integration Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure seamless interaction between models, controllers, and role-based access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Role-Based Access:&lt;br /&gt;
** Verify only authorized roles (e.g., Admin, Instructor) can manage notifications.&lt;br /&gt;
** Ensure students can only view notifications for their enrolled courses.&lt;br /&gt;
* Full CRUD Workflow:&lt;br /&gt;
** Test end-to-end creation, updating, and deletion of notifications.&lt;br /&gt;
* Error Scenarios:&lt;br /&gt;
** Handle cases where a notification is created for a non-existent course or user.&lt;br /&gt;
** Verify appropriate error messages for unauthorized actions.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications Integration', type: :request do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let!(:notification) { create(:notification, user: admin) }&lt;br /&gt;
  it 'allows admins to create notifications' do&lt;br /&gt;
    sign_in admin&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:created)&lt;br /&gt;
  end&lt;br /&gt;
  it 'prevents students from creating notifications' do&lt;br /&gt;
    sign_in student&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:forbidden)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''4. API Documentation and Testing with RSwag'''&lt;br /&gt;
&lt;br /&gt;
Goal: Generate API documentation and test all endpoints.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get 'Retrieve notifications' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      response '200', 'success' do&lt;br /&gt;
        schema type: :array, items: { type: :object, properties: { id: { type: :integer }, subject: { type: :string } } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    post 'Create a notification' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: 'date' },&lt;br /&gt;
          is_active: { type: :boolean }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject description expiration_date]&lt;br /&gt;
      }&lt;br /&gt;
      response '201', 'created' do&lt;br /&gt;
        let(:notification) { { subject: 'Test', description: 'Test notification', expiration_date: '2024-12-31', is_active: true } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160670</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160670"/>
		<updated>2024-12-04T04:45:52Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* New Files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== New Files ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Model for Notification (models/notification.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class Notification &amp;lt; ApplicationRecord&lt;br /&gt;
  # Associations&lt;br /&gt;
  belongs_to :course, foreign_key: :course_name, primary_key: :name&lt;br /&gt;
  belongs_to :user&lt;br /&gt;
  # Validations&lt;br /&gt;
  validates :subject, presence: true, length: { maximum: 255 }&lt;br /&gt;
  validates :description, presence: true&lt;br /&gt;
  validates :expiration_date, presence: true&lt;br /&gt;
  validate :expiration_date_cannot_be_in_the_past&lt;br /&gt;
  # Scopes&lt;br /&gt;
  scope :active, -&amp;gt; { where(active_flag: true) }&lt;br /&gt;
  scope :expired, -&amp;gt; { where('expiration_date &amp;lt; ?', Date.today) }&lt;br /&gt;
  scope :unread_by, -&amp;gt;(user) {&lt;br /&gt;
    joins(:course).where(courses: { id: user.assignments.pluck(:course_id) }).where(active_flag: true)&lt;br /&gt;
  }&lt;br /&gt;
  # Custom Validation for Expiration Date&lt;br /&gt;
  def expiration_date_cannot_be_in_the_past&lt;br /&gt;
    if expiration_date.present? &amp;amp;&amp;amp; expiration_date &amp;lt; Date.today&lt;br /&gt;
      errors.add(:expiration_date, &amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; 2. Controller for Notification (controllers/notification_controller.rb)&lt;br /&gt;
&lt;br /&gt;
class Api::V1::NotificationsController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_notification, only: %i[show update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /notifications&lt;br /&gt;
  def index&lt;br /&gt;
    if current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      @notifications = Notification.where(user_id: current_user.id)&lt;br /&gt;
    elsif current_user_has_student_privileges?&lt;br /&gt;
      course_names = current_user.courses.pluck(:name)&lt;br /&gt;
      @notifications = Notification.where(course_name: course_names, active_flag: true)&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Access denied' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    render json: @notifications&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /notifications/:id&lt;br /&gt;
  def show&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      render json: @notification&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You do not have access to this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /notifications&lt;br /&gt;
  def create&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to create notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @notification = Notification.new(notification_params)&lt;br /&gt;
    @notification.user_id = current_user.id&lt;br /&gt;
  &lt;br /&gt;
    if @notification.save&lt;br /&gt;
      render json: @notification, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /notifications/:id&lt;br /&gt;
  def update&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to update notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    if @notification.update(notification_params)&lt;br /&gt;
      render json: @notification, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: @notification.errors, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  # DELETE /notifications/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    # Check if the current user has sufficient privileges&lt;br /&gt;
    unless current_user_has_instructor_privileges? || current_user_has_ta_privileges?&lt;br /&gt;
      render json: { error: 'You are not authorized to delete notifications.' }, status: :forbidden&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    if @notification.destroy&lt;br /&gt;
      render json: { message: 'Notification deleted successfully.' }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'Failed to delete the notification.' }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  # PATCH /notifications/:id/toggle_active&lt;br /&gt;
  def toggle_notification_visibility&lt;br /&gt;
    if notification_accessible?(@notification)&lt;br /&gt;
      @notification.update(active_flag: !@notification.active_flag)&lt;br /&gt;
      render json: { message: 'Notification visibility toggled successfully.', notification: @notification }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { error: 'You are not authorized to toggle this notification.' }, status: :forbidden&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_notification&lt;br /&gt;
    @notification = Notification.find(params[:id])&lt;br /&gt;
  rescue ActiveRecord::RecordNotFound&lt;br /&gt;
    render json: { error: 'Notification not found.' }, status: :not_found&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Define strong parameters for notification creation/update&lt;br /&gt;
  def notification_params&lt;br /&gt;
    params.require(:notification).permit(:course_name, :subject, :description, :expiration_date, :active_flag)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Helper method to check if a notification is accessible to the current user&lt;br /&gt;
  def notification_accessible?(notification)&lt;br /&gt;
    # Instructors and TAs can access their own notifications&lt;br /&gt;
    return true if notification.user_id == current_user.id&lt;br /&gt;
&lt;br /&gt;
    # Students can access notifications for their courses&lt;br /&gt;
    return true if current_user_has_student_privileges? &amp;amp;&amp;amp;&lt;br /&gt;
                   current_user.courses.exists?(name: notification.course_name)&lt;br /&gt;
&lt;br /&gt;
    false&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
3. Spec for Controller (spec/requests/api/v1/notification_controller.rb)&lt;br /&gt;
&lt;br /&gt;
require 'swagger_helper'&lt;br /&gt;
&lt;br /&gt;
RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  let(:user) { create(:user, name: 'test_user') }&lt;br /&gt;
  let(:course) { create(:course, name: 'Ruby 101', instructor_id: user.id, institution_id: 1) }&lt;br /&gt;
  let(:notification) { create(:notification, course: course, user: user, subject: 'Test Notification') }&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get('list notifications') do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
&lt;br /&gt;
      response(200, 'Success') do&lt;br /&gt;
        let!(:notifications) { create_list(:notification, 5, user: user, course: course) }&lt;br /&gt;
&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do |response|&lt;br /&gt;
          expect(JSON.parse(response.body).size).to eq(5)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    post('create notification') do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: :date },&lt;br /&gt;
          active_flag: { type: :boolean },&lt;br /&gt;
          course_id: { type: :integer }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject course_id]&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      response(201, 'Created') do&lt;br /&gt;
        let(:notification) { { subject: 'New Notification', description: 'Details', expiration_date: Date.today + 7, course_id: course.id } }&lt;br /&gt;
&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      response(422, 'Unprocessable Entity') do&lt;br /&gt;
        let(:notification) { { description: 'Details', expiration_date: Date.today + 7, course_id: course.id } }&lt;br /&gt;
&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/notifications/{id}' do&lt;br /&gt;
    parameter name: :id, in: :path, type: :integer, description: 'ID of the notification'&lt;br /&gt;
&lt;br /&gt;
    get('show notification') do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      response(200, 'Success') do&lt;br /&gt;
        let(:id) { notification.id }&lt;br /&gt;
&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      response(404, 'Not Found') do&lt;br /&gt;
        let(:id) { 'INVALID' }&lt;br /&gt;
&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    patch('update notification') do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: :date },&lt;br /&gt;
          active_flag: { type: :boolean }&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      response(200, 'Updated') do&lt;br /&gt;
        let(:id) { notification.id }&lt;br /&gt;
        let(:notification) { { subject: 'Updated Notification', active_flag: true } }&lt;br /&gt;
&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      response(404, 'Not Found') do&lt;br /&gt;
        let(:id) { 'INVALID' }&lt;br /&gt;
        let(:notification) { { subject: 'Updated Notification', active_flag: true } }&lt;br /&gt;
&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    delete('delete notification') do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
&lt;br /&gt;
      response(204, 'Deleted') do&lt;br /&gt;
        let(:id) { notification.id }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      response(404, 'Not Found') do&lt;br /&gt;
        let(:id) { 'INVALID' }&lt;br /&gt;
&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/notifications/{id}/toggle_active' do&lt;br /&gt;
    parameter name: :id, in: :path, type: :integer, description: 'ID of the notification'&lt;br /&gt;
&lt;br /&gt;
    patch('toggle notification visibility') do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
&lt;br /&gt;
      response(200, 'Visibility toggled') do&lt;br /&gt;
        let(:id) { notification.id }&lt;br /&gt;
&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      response(404, 'Not Found') do&lt;br /&gt;
        let(:id) { 'INVALID' }&lt;br /&gt;
&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; 4. Tests for Model (spec/models/notification_spec.rb)&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
&lt;br /&gt;
RSpec.describe Notification, type: :model do&lt;br /&gt;
  before(:each) do&lt;br /&gt;
    # Mock the course and user&lt;br /&gt;
    @course = instance_double(Course, name: &amp;quot;Ruby 101&amp;quot;)&lt;br /&gt;
    role = instance_double(Role, id: 1, name: &amp;quot;Student&amp;quot;)&lt;br /&gt;
    @user = instance_double(User, id: 1, name: &amp;quot;Test User&amp;quot;, email: &amp;quot;test@example.com&amp;quot;, role: role)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it 'is invalid without a subject' do&lt;br /&gt;
      notification = Notification.new(subject: nil)&lt;br /&gt;
      expect(notification).not_to be_valid&lt;br /&gt;
      expect(notification.errors[:subject]).to include(&amp;quot;can't be blank&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'is invalid without a description' do&lt;br /&gt;
      notification = Notification.new(description: nil)&lt;br /&gt;
      expect(notification).not_to be_valid&lt;br /&gt;
      expect(notification.errors[:description]).to include(&amp;quot;can't be blank&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'is invalid without an expiration_date' do&lt;br /&gt;
      notification = Notification.new(expiration_date: nil)&lt;br /&gt;
      expect(notification).not_to be_valid&lt;br /&gt;
      expect(notification.errors[:expiration_date]).to include(&amp;quot;can't be blank&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'is invalid if expiration_date is in the past' do&lt;br /&gt;
      notification = Notification.new(expiration_date: Date.yesterday)&lt;br /&gt;
      expect(notification).not_to be_valid&lt;br /&gt;
      expect(notification.errors[:expiration_date]).to include(&amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it 'belongs to a course' do&lt;br /&gt;
      # Mock the course association&lt;br /&gt;
      notification = Notification.new&lt;br /&gt;
      allow(notification).to receive(:course).and_return(@course)&lt;br /&gt;
&lt;br /&gt;
      # Test that the association returns the mocked course&lt;br /&gt;
      expect(notification.course).to eq(@course)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'belongs to a user' do&lt;br /&gt;
      # Mock the user association&lt;br /&gt;
      notification = Notification.new&lt;br /&gt;
      allow(notification).to receive(:user).and_return(@user)&lt;br /&gt;
&lt;br /&gt;
      # Test that the association returns the mocked user&lt;br /&gt;
      expect(notification.user).to eq(@user)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      @notification1 = instance_double(&lt;br /&gt;
        Notification,&lt;br /&gt;
        subject: &amp;quot;Active Notification&amp;quot;,&lt;br /&gt;
        expiration_date: Date.today + 3,&lt;br /&gt;
        active_flag: true,&lt;br /&gt;
        course_name: @course.name,&lt;br /&gt;
        user: @user&lt;br /&gt;
      )&lt;br /&gt;
&lt;br /&gt;
      @notification2 = instance_double(&lt;br /&gt;
        Notification,&lt;br /&gt;
        subject: &amp;quot;Expired Notification&amp;quot;,&lt;br /&gt;
        expiration_date: Date.yesterday,&lt;br /&gt;
        active_flag: true,&lt;br /&gt;
        course_name: @course.name,&lt;br /&gt;
        user: @user&lt;br /&gt;
      )&lt;br /&gt;
&lt;br /&gt;
      @notification3 = instance_double(&lt;br /&gt;
        Notification,&lt;br /&gt;
        subject: &amp;quot;Inactive Notification&amp;quot;,&lt;br /&gt;
        expiration_date: Date.today + 7,&lt;br /&gt;
        active_flag: false,&lt;br /&gt;
        course_name: @course.name,&lt;br /&gt;
        user: @user&lt;br /&gt;
      )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    describe '.active' do&lt;br /&gt;
      it 'returns notifications that are active' do&lt;br /&gt;
        allow(Notification).to receive(:active).and_return([@notification1])&lt;br /&gt;
        expect(Notification.active).to include(@notification1)&lt;br /&gt;
        expect(Notification.active).not_to include(@notification2, @notification3)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    describe '.expired' do&lt;br /&gt;
      it 'returns notifications that are expired' do&lt;br /&gt;
        allow(Notification).to receive(:expired).and_return([@notification2])&lt;br /&gt;
        expect(Notification.expired).to include(@notification2)&lt;br /&gt;
        expect(Notification.expired).not_to include(@notification1, @notification3)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    describe '.unread_by' do&lt;br /&gt;
      it 'returns notifications that are unread by the user' do&lt;br /&gt;
        allow(Notification).to receive(:unread_by).with(@user).and_return([@notification1])&lt;br /&gt;
        unread_notifications = Notification.unread_by(@user)&lt;br /&gt;
        expect(unread_notifications).to include(@notification1)&lt;br /&gt;
        expect(unread_notifications).not_to include(@notification2, @notification3)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Singleton Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Managing a global notification scheduler or manager, ensuring that only one instance exists.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Singleton Pattern ensures that there is only one centralized manager for handling notification-related tasks, such as scheduling or batch operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;4. Chain of Responsibility Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Modularizing the validation logic for notifications (e.g., checking permissions, validating expiration dates, ensuring uniqueness).&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Chain of Responsibility Pattern allows you to break down validation or processing logic into discrete steps, improving code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Following are the some of the SOLID principles with how they will be applied to the back-end development:&amp;lt;/b&amp;gt;&lt;br /&gt;
* Single Responsibility : Controllers handle HTTP requests, models handle data, and service objects handle business logic (e.g., sending notifications).&lt;br /&gt;
* Open/Closed : Extend functionality (e.g., new notification types or filters) by adding new classes or methods without modifying existing code.&lt;br /&gt;
* Interface Segregation : Create small, role-specific interfaces (e.g., policies for TAs, students, instructors) and separate service objects for different types of notifications.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
This section outlines the comprehensive testing approach for the Notifications feature to ensure it meets functional and non-functional requirements. The strategy includes detailed test cases for models, controllers, role-based access, and error handling, leveraging RSpec for testing and RSwag for API documentation.&lt;br /&gt;
&lt;br /&gt;
'''1. Unit Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure that the Notification model functions as expected by validating its attributes, associations, and methods.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
* Validations:&lt;br /&gt;
** Presence validation for subject, description, expiration_date, course_id, and user_id.&lt;br /&gt;
** Length constraints on subject and description.&lt;br /&gt;
** Format validation for expiration_date.&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :user and belongs_to :course associations are correctly established.&lt;br /&gt;
** Notifications have appropriate relationships with Course and User models.&lt;br /&gt;
&lt;br /&gt;
* Custom Methods and Scopes:&lt;br /&gt;
** active_notifications: Ensure only active notifications are returned.&lt;br /&gt;
** unread_notifications: Validate that unread notifications are fetched correctly.&lt;br /&gt;
&lt;br /&gt;
* Edge Cases:&lt;br /&gt;
** Notifications with an expired expiration_date should not appear in the active notifications list.&lt;br /&gt;
** Handling invalid foreign keys for user_id and course_id.&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe Notification, type: :model do&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it { should validate_presence_of(:subject) }&lt;br /&gt;
    it { should validate_presence_of(:description) }&lt;br /&gt;
    it { should validate_presence_of(:expiration_date) }&lt;br /&gt;
    it { should validate_length_of(:subject).is_at_most(100) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it { should belong_to(:user) }&lt;br /&gt;
    it { should belong_to(:course) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    let!(:active_notification) { create(:notification, is_active: true) }&lt;br /&gt;
    let!(:expired_notification) { create(:notification, expiration_date: Date.yesterday) }&lt;br /&gt;
    it 'returns active notifications' do&lt;br /&gt;
      expect(Notification.active_notifications).to include(active_notification)&lt;br /&gt;
      expect(Notification.active_notifications).not_to include(expired_notification)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Controller Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Test all CRUD operations for the Notifications controller to ensure endpoints function as expected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Index Action:&lt;br /&gt;
** Ensure all notifications for a given user are returned.&lt;br /&gt;
** Verify that unauthorized users cannot access the endpoint.&lt;br /&gt;
** Test paginated responses if applicable.&lt;br /&gt;
* Show Action:&lt;br /&gt;
** Ensure notifications can be retrieved by id.&lt;br /&gt;
** Handle cases where id is invalid or unauthorized.&lt;br /&gt;
* Create Action:&lt;br /&gt;
** Validate successful creation of notifications with proper attributes.&lt;br /&gt;
** Handle validation failures and unauthorized access.&lt;br /&gt;
* Update Action:&lt;br /&gt;
** Test updates to notification attributes.&lt;br /&gt;
** Ensure unauthorized users cannot perform updates.&lt;br /&gt;
* Delete Action:&lt;br /&gt;
** Verify notifications are deleted successfully.&lt;br /&gt;
** Test behavior when id is invalid or unauthorized.&lt;br /&gt;
&lt;br /&gt;
 require 'rails_helper'&lt;br /&gt;
 RSpec.describe Api::V1::NotificationsController, type: :controller do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let(:notification) { create(:notification) }&lt;br /&gt;
  describe 'GET #index' do&lt;br /&gt;
    before { sign_in admin }&lt;br /&gt;
    it 'returns notifications for the current user' do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:ok)&lt;br /&gt;
      expect(json_response).to include(notification)&lt;br /&gt;
    end&lt;br /&gt;
    it 'denies access to unauthorized users' do&lt;br /&gt;
      sign_out admin&lt;br /&gt;
      sign_in student&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:forbidden)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  describe 'POST #create' do&lt;br /&gt;
    context 'with valid attributes' do&lt;br /&gt;
      it 'creates a new notification' do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { notification: attributes_for(:notification) }&lt;br /&gt;
        }.to change(Notification, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'with invalid attributes' do&lt;br /&gt;
      it 'returns validation errors' do&lt;br /&gt;
        post :create, params: { notification: { subject: '' } }&lt;br /&gt;
        expect(response).to have_http_status(:unprocessable_entity)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''3. Integration Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure seamless interaction between models, controllers, and role-based access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Role-Based Access:&lt;br /&gt;
** Verify only authorized roles (e.g., Admin, Instructor) can manage notifications.&lt;br /&gt;
** Ensure students can only view notifications for their enrolled courses.&lt;br /&gt;
* Full CRUD Workflow:&lt;br /&gt;
** Test end-to-end creation, updating, and deletion of notifications.&lt;br /&gt;
* Error Scenarios:&lt;br /&gt;
** Handle cases where a notification is created for a non-existent course or user.&lt;br /&gt;
** Verify appropriate error messages for unauthorized actions.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications Integration', type: :request do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let!(:notification) { create(:notification, user: admin) }&lt;br /&gt;
  it 'allows admins to create notifications' do&lt;br /&gt;
    sign_in admin&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:created)&lt;br /&gt;
  end&lt;br /&gt;
  it 'prevents students from creating notifications' do&lt;br /&gt;
    sign_in student&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:forbidden)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''4. API Documentation and Testing with RSwag'''&lt;br /&gt;
&lt;br /&gt;
Goal: Generate API documentation and test all endpoints.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get 'Retrieve notifications' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      response '200', 'success' do&lt;br /&gt;
        schema type: :array, items: { type: :object, properties: { id: { type: :integer }, subject: { type: :string } } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    post 'Create a notification' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: 'date' },&lt;br /&gt;
          is_active: { type: :boolean }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject description expiration_date]&lt;br /&gt;
      }&lt;br /&gt;
      response '201', 'created' do&lt;br /&gt;
        let(:notification) { { subject: 'Test', description: 'Test notification', expiration_date: '2024-12-31', is_active: true } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160665</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160665"/>
		<updated>2024-12-04T04:37:52Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* New Files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== New Files ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Model for Notification (models/notification.rb) &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class Notification &amp;lt; ApplicationRecord&lt;br /&gt;
  # Associations&lt;br /&gt;
  belongs_to :course, foreign_key: :course_name, primary_key: :name&lt;br /&gt;
  belongs_to :user&lt;br /&gt;
  # Validations&lt;br /&gt;
  validates :subject, presence: true, length: { maximum: 255 }&lt;br /&gt;
  validates :description, presence: true&lt;br /&gt;
  validates :expiration_date, presence: true&lt;br /&gt;
  validate :expiration_date_cannot_be_in_the_past&lt;br /&gt;
  # Scopes&lt;br /&gt;
  scope :active, -&amp;gt; { where(active_flag: true) }&lt;br /&gt;
  scope :expired, -&amp;gt; { where('expiration_date &amp;lt; ?', Date.today) }&lt;br /&gt;
  scope :unread_by, -&amp;gt;(user) {&lt;br /&gt;
    joins(:course).where(courses: { id: user.assignments.pluck(:course_id) }).where(active_flag: true)&lt;br /&gt;
  }&lt;br /&gt;
  # Custom Validation for Expiration Date&lt;br /&gt;
  def expiration_date_cannot_be_in_the_past&lt;br /&gt;
    if expiration_date.present? &amp;amp;&amp;amp; expiration_date &amp;lt; Date.today&lt;br /&gt;
      errors.add(:expiration_date, &amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Singleton Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Managing a global notification scheduler or manager, ensuring that only one instance exists.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Singleton Pattern ensures that there is only one centralized manager for handling notification-related tasks, such as scheduling or batch operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;4. Chain of Responsibility Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Modularizing the validation logic for notifications (e.g., checking permissions, validating expiration dates, ensuring uniqueness).&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Chain of Responsibility Pattern allows you to break down validation or processing logic into discrete steps, improving code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Following are the some of the SOLID principles with how they will be applied to the back-end development:&amp;lt;/b&amp;gt;&lt;br /&gt;
* Single Responsibility : Controllers handle HTTP requests, models handle data, and service objects handle business logic (e.g., sending notifications).&lt;br /&gt;
* Open/Closed : Extend functionality (e.g., new notification types or filters) by adding new classes or methods without modifying existing code.&lt;br /&gt;
* Interface Segregation : Create small, role-specific interfaces (e.g., policies for TAs, students, instructors) and separate service objects for different types of notifications.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
This section outlines the comprehensive testing approach for the Notifications feature to ensure it meets functional and non-functional requirements. The strategy includes detailed test cases for models, controllers, role-based access, and error handling, leveraging RSpec for testing and RSwag for API documentation.&lt;br /&gt;
&lt;br /&gt;
'''1. Unit Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure that the Notification model functions as expected by validating its attributes, associations, and methods.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
* Validations:&lt;br /&gt;
** Presence validation for subject, description, expiration_date, course_id, and user_id.&lt;br /&gt;
** Length constraints on subject and description.&lt;br /&gt;
** Format validation for expiration_date.&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :user and belongs_to :course associations are correctly established.&lt;br /&gt;
** Notifications have appropriate relationships with Course and User models.&lt;br /&gt;
&lt;br /&gt;
* Custom Methods and Scopes:&lt;br /&gt;
** active_notifications: Ensure only active notifications are returned.&lt;br /&gt;
** unread_notifications: Validate that unread notifications are fetched correctly.&lt;br /&gt;
&lt;br /&gt;
* Edge Cases:&lt;br /&gt;
** Notifications with an expired expiration_date should not appear in the active notifications list.&lt;br /&gt;
** Handling invalid foreign keys for user_id and course_id.&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe Notification, type: :model do&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it { should validate_presence_of(:subject) }&lt;br /&gt;
    it { should validate_presence_of(:description) }&lt;br /&gt;
    it { should validate_presence_of(:expiration_date) }&lt;br /&gt;
    it { should validate_length_of(:subject).is_at_most(100) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it { should belong_to(:user) }&lt;br /&gt;
    it { should belong_to(:course) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    let!(:active_notification) { create(:notification, is_active: true) }&lt;br /&gt;
    let!(:expired_notification) { create(:notification, expiration_date: Date.yesterday) }&lt;br /&gt;
    it 'returns active notifications' do&lt;br /&gt;
      expect(Notification.active_notifications).to include(active_notification)&lt;br /&gt;
      expect(Notification.active_notifications).not_to include(expired_notification)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Controller Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Test all CRUD operations for the Notifications controller to ensure endpoints function as expected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Index Action:&lt;br /&gt;
** Ensure all notifications for a given user are returned.&lt;br /&gt;
** Verify that unauthorized users cannot access the endpoint.&lt;br /&gt;
** Test paginated responses if applicable.&lt;br /&gt;
* Show Action:&lt;br /&gt;
** Ensure notifications can be retrieved by id.&lt;br /&gt;
** Handle cases where id is invalid or unauthorized.&lt;br /&gt;
* Create Action:&lt;br /&gt;
** Validate successful creation of notifications with proper attributes.&lt;br /&gt;
** Handle validation failures and unauthorized access.&lt;br /&gt;
* Update Action:&lt;br /&gt;
** Test updates to notification attributes.&lt;br /&gt;
** Ensure unauthorized users cannot perform updates.&lt;br /&gt;
* Delete Action:&lt;br /&gt;
** Verify notifications are deleted successfully.&lt;br /&gt;
** Test behavior when id is invalid or unauthorized.&lt;br /&gt;
&lt;br /&gt;
 require 'rails_helper'&lt;br /&gt;
 RSpec.describe Api::V1::NotificationsController, type: :controller do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let(:notification) { create(:notification) }&lt;br /&gt;
  describe 'GET #index' do&lt;br /&gt;
    before { sign_in admin }&lt;br /&gt;
    it 'returns notifications for the current user' do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:ok)&lt;br /&gt;
      expect(json_response).to include(notification)&lt;br /&gt;
    end&lt;br /&gt;
    it 'denies access to unauthorized users' do&lt;br /&gt;
      sign_out admin&lt;br /&gt;
      sign_in student&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:forbidden)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  describe 'POST #create' do&lt;br /&gt;
    context 'with valid attributes' do&lt;br /&gt;
      it 'creates a new notification' do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { notification: attributes_for(:notification) }&lt;br /&gt;
        }.to change(Notification, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'with invalid attributes' do&lt;br /&gt;
      it 'returns validation errors' do&lt;br /&gt;
        post :create, params: { notification: { subject: '' } }&lt;br /&gt;
        expect(response).to have_http_status(:unprocessable_entity)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''3. Integration Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure seamless interaction between models, controllers, and role-based access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Role-Based Access:&lt;br /&gt;
** Verify only authorized roles (e.g., Admin, Instructor) can manage notifications.&lt;br /&gt;
** Ensure students can only view notifications for their enrolled courses.&lt;br /&gt;
* Full CRUD Workflow:&lt;br /&gt;
** Test end-to-end creation, updating, and deletion of notifications.&lt;br /&gt;
* Error Scenarios:&lt;br /&gt;
** Handle cases where a notification is created for a non-existent course or user.&lt;br /&gt;
** Verify appropriate error messages for unauthorized actions.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications Integration', type: :request do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let!(:notification) { create(:notification, user: admin) }&lt;br /&gt;
  it 'allows admins to create notifications' do&lt;br /&gt;
    sign_in admin&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:created)&lt;br /&gt;
  end&lt;br /&gt;
  it 'prevents students from creating notifications' do&lt;br /&gt;
    sign_in student&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:forbidden)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''4. API Documentation and Testing with RSwag'''&lt;br /&gt;
&lt;br /&gt;
Goal: Generate API documentation and test all endpoints.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get 'Retrieve notifications' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      response '200', 'success' do&lt;br /&gt;
        schema type: :array, items: { type: :object, properties: { id: { type: :integer }, subject: { type: :string } } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    post 'Create a notification' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: 'date' },&lt;br /&gt;
          is_active: { type: :boolean }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject description expiration_date]&lt;br /&gt;
      }&lt;br /&gt;
      response '201', 'created' do&lt;br /&gt;
        let(:notification) { { subject: 'Test', description: 'Test notification', expiration_date: '2024-12-31', is_active: true } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160661</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160661"/>
		<updated>2024-12-04T04:37:02Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* New Files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== New Files ==&lt;br /&gt;
&lt;br /&gt;
1. Model for Notification (models/notification.rb) &lt;br /&gt;
&lt;br /&gt;
class Notification &amp;lt; ApplicationRecord&lt;br /&gt;
  # Associations&lt;br /&gt;
  belongs_to :course, foreign_key: :course_name, primary_key: :name&lt;br /&gt;
  belongs_to :user&lt;br /&gt;
&lt;br /&gt;
  # Validations&lt;br /&gt;
  validates :subject, presence: true, length: { maximum: 255 }&lt;br /&gt;
  validates :description, presence: true&lt;br /&gt;
  validates :expiration_date, presence: true&lt;br /&gt;
  validate :expiration_date_cannot_be_in_the_past&lt;br /&gt;
&lt;br /&gt;
  # Scopes&lt;br /&gt;
  scope :active, -&amp;gt; { where(active_flag: true) }&lt;br /&gt;
  scope :expired, -&amp;gt; { where('expiration_date &amp;lt; ?', Date.today) }&lt;br /&gt;
  scope :unread_by, -&amp;gt;(user) {&lt;br /&gt;
    joins(:course).where(courses: { id: user.assignments.pluck(:course_id) }).where(active_flag: true)&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  # Custom Validation for Expiration Date&lt;br /&gt;
  def expiration_date_cannot_be_in_the_past&lt;br /&gt;
    if expiration_date.present? &amp;amp;&amp;amp; expiration_date &amp;lt; Date.today&lt;br /&gt;
      errors.add(:expiration_date, &amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Singleton Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Managing a global notification scheduler or manager, ensuring that only one instance exists.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Singleton Pattern ensures that there is only one centralized manager for handling notification-related tasks, such as scheduling or batch operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;4. Chain of Responsibility Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Modularizing the validation logic for notifications (e.g., checking permissions, validating expiration dates, ensuring uniqueness).&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Chain of Responsibility Pattern allows you to break down validation or processing logic into discrete steps, improving code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Following are the some of the SOLID principles with how they will be applied to the back-end development:&amp;lt;/b&amp;gt;&lt;br /&gt;
* Single Responsibility : Controllers handle HTTP requests, models handle data, and service objects handle business logic (e.g., sending notifications).&lt;br /&gt;
* Open/Closed : Extend functionality (e.g., new notification types or filters) by adding new classes or methods without modifying existing code.&lt;br /&gt;
* Interface Segregation : Create small, role-specific interfaces (e.g., policies for TAs, students, instructors) and separate service objects for different types of notifications.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
This section outlines the comprehensive testing approach for the Notifications feature to ensure it meets functional and non-functional requirements. The strategy includes detailed test cases for models, controllers, role-based access, and error handling, leveraging RSpec for testing and RSwag for API documentation.&lt;br /&gt;
&lt;br /&gt;
'''1. Unit Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure that the Notification model functions as expected by validating its attributes, associations, and methods.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
* Validations:&lt;br /&gt;
** Presence validation for subject, description, expiration_date, course_id, and user_id.&lt;br /&gt;
** Length constraints on subject and description.&lt;br /&gt;
** Format validation for expiration_date.&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :user and belongs_to :course associations are correctly established.&lt;br /&gt;
** Notifications have appropriate relationships with Course and User models.&lt;br /&gt;
&lt;br /&gt;
* Custom Methods and Scopes:&lt;br /&gt;
** active_notifications: Ensure only active notifications are returned.&lt;br /&gt;
** unread_notifications: Validate that unread notifications are fetched correctly.&lt;br /&gt;
&lt;br /&gt;
* Edge Cases:&lt;br /&gt;
** Notifications with an expired expiration_date should not appear in the active notifications list.&lt;br /&gt;
** Handling invalid foreign keys for user_id and course_id.&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe Notification, type: :model do&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it { should validate_presence_of(:subject) }&lt;br /&gt;
    it { should validate_presence_of(:description) }&lt;br /&gt;
    it { should validate_presence_of(:expiration_date) }&lt;br /&gt;
    it { should validate_length_of(:subject).is_at_most(100) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it { should belong_to(:user) }&lt;br /&gt;
    it { should belong_to(:course) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    let!(:active_notification) { create(:notification, is_active: true) }&lt;br /&gt;
    let!(:expired_notification) { create(:notification, expiration_date: Date.yesterday) }&lt;br /&gt;
    it 'returns active notifications' do&lt;br /&gt;
      expect(Notification.active_notifications).to include(active_notification)&lt;br /&gt;
      expect(Notification.active_notifications).not_to include(expired_notification)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Controller Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Test all CRUD operations for the Notifications controller to ensure endpoints function as expected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Index Action:&lt;br /&gt;
** Ensure all notifications for a given user are returned.&lt;br /&gt;
** Verify that unauthorized users cannot access the endpoint.&lt;br /&gt;
** Test paginated responses if applicable.&lt;br /&gt;
* Show Action:&lt;br /&gt;
** Ensure notifications can be retrieved by id.&lt;br /&gt;
** Handle cases where id is invalid or unauthorized.&lt;br /&gt;
* Create Action:&lt;br /&gt;
** Validate successful creation of notifications with proper attributes.&lt;br /&gt;
** Handle validation failures and unauthorized access.&lt;br /&gt;
* Update Action:&lt;br /&gt;
** Test updates to notification attributes.&lt;br /&gt;
** Ensure unauthorized users cannot perform updates.&lt;br /&gt;
* Delete Action:&lt;br /&gt;
** Verify notifications are deleted successfully.&lt;br /&gt;
** Test behavior when id is invalid or unauthorized.&lt;br /&gt;
&lt;br /&gt;
 require 'rails_helper'&lt;br /&gt;
 RSpec.describe Api::V1::NotificationsController, type: :controller do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let(:notification) { create(:notification) }&lt;br /&gt;
  describe 'GET #index' do&lt;br /&gt;
    before { sign_in admin }&lt;br /&gt;
    it 'returns notifications for the current user' do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:ok)&lt;br /&gt;
      expect(json_response).to include(notification)&lt;br /&gt;
    end&lt;br /&gt;
    it 'denies access to unauthorized users' do&lt;br /&gt;
      sign_out admin&lt;br /&gt;
      sign_in student&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:forbidden)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  describe 'POST #create' do&lt;br /&gt;
    context 'with valid attributes' do&lt;br /&gt;
      it 'creates a new notification' do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { notification: attributes_for(:notification) }&lt;br /&gt;
        }.to change(Notification, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'with invalid attributes' do&lt;br /&gt;
      it 'returns validation errors' do&lt;br /&gt;
        post :create, params: { notification: { subject: '' } }&lt;br /&gt;
        expect(response).to have_http_status(:unprocessable_entity)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''3. Integration Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure seamless interaction between models, controllers, and role-based access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Role-Based Access:&lt;br /&gt;
** Verify only authorized roles (e.g., Admin, Instructor) can manage notifications.&lt;br /&gt;
** Ensure students can only view notifications for their enrolled courses.&lt;br /&gt;
* Full CRUD Workflow:&lt;br /&gt;
** Test end-to-end creation, updating, and deletion of notifications.&lt;br /&gt;
* Error Scenarios:&lt;br /&gt;
** Handle cases where a notification is created for a non-existent course or user.&lt;br /&gt;
** Verify appropriate error messages for unauthorized actions.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications Integration', type: :request do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let!(:notification) { create(:notification, user: admin) }&lt;br /&gt;
  it 'allows admins to create notifications' do&lt;br /&gt;
    sign_in admin&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:created)&lt;br /&gt;
  end&lt;br /&gt;
  it 'prevents students from creating notifications' do&lt;br /&gt;
    sign_in student&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:forbidden)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''4. API Documentation and Testing with RSwag'''&lt;br /&gt;
&lt;br /&gt;
Goal: Generate API documentation and test all endpoints.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get 'Retrieve notifications' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      response '200', 'success' do&lt;br /&gt;
        schema type: :array, items: { type: :object, properties: { id: { type: :integer }, subject: { type: :string } } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    post 'Create a notification' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: 'date' },&lt;br /&gt;
          is_active: { type: :boolean }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject description expiration_date]&lt;br /&gt;
      }&lt;br /&gt;
      response '201', 'created' do&lt;br /&gt;
        let(:notification) { { subject: 'Test', description: 'Test notification', expiration_date: '2024-12-31', is_active: true } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160660</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160660"/>
		<updated>2024-12-04T04:36:38Z</updated>

		<summary type="html">&lt;p&gt;Akilled: Undo revision 160659 by Akilled (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== New Files ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Singleton Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Managing a global notification scheduler or manager, ensuring that only one instance exists.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Singleton Pattern ensures that there is only one centralized manager for handling notification-related tasks, such as scheduling or batch operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;4. Chain of Responsibility Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Modularizing the validation logic for notifications (e.g., checking permissions, validating expiration dates, ensuring uniqueness).&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Chain of Responsibility Pattern allows you to break down validation or processing logic into discrete steps, improving code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Following are the some of the SOLID principles with how they will be applied to the back-end development:&amp;lt;/b&amp;gt;&lt;br /&gt;
* Single Responsibility : Controllers handle HTTP requests, models handle data, and service objects handle business logic (e.g., sending notifications).&lt;br /&gt;
* Open/Closed : Extend functionality (e.g., new notification types or filters) by adding new classes or methods without modifying existing code.&lt;br /&gt;
* Interface Segregation : Create small, role-specific interfaces (e.g., policies for TAs, students, instructors) and separate service objects for different types of notifications.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
This section outlines the comprehensive testing approach for the Notifications feature to ensure it meets functional and non-functional requirements. The strategy includes detailed test cases for models, controllers, role-based access, and error handling, leveraging RSpec for testing and RSwag for API documentation.&lt;br /&gt;
&lt;br /&gt;
'''1. Unit Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure that the Notification model functions as expected by validating its attributes, associations, and methods.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
* Validations:&lt;br /&gt;
** Presence validation for subject, description, expiration_date, course_id, and user_id.&lt;br /&gt;
** Length constraints on subject and description.&lt;br /&gt;
** Format validation for expiration_date.&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :user and belongs_to :course associations are correctly established.&lt;br /&gt;
** Notifications have appropriate relationships with Course and User models.&lt;br /&gt;
&lt;br /&gt;
* Custom Methods and Scopes:&lt;br /&gt;
** active_notifications: Ensure only active notifications are returned.&lt;br /&gt;
** unread_notifications: Validate that unread notifications are fetched correctly.&lt;br /&gt;
&lt;br /&gt;
* Edge Cases:&lt;br /&gt;
** Notifications with an expired expiration_date should not appear in the active notifications list.&lt;br /&gt;
** Handling invalid foreign keys for user_id and course_id.&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe Notification, type: :model do&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it { should validate_presence_of(:subject) }&lt;br /&gt;
    it { should validate_presence_of(:description) }&lt;br /&gt;
    it { should validate_presence_of(:expiration_date) }&lt;br /&gt;
    it { should validate_length_of(:subject).is_at_most(100) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it { should belong_to(:user) }&lt;br /&gt;
    it { should belong_to(:course) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    let!(:active_notification) { create(:notification, is_active: true) }&lt;br /&gt;
    let!(:expired_notification) { create(:notification, expiration_date: Date.yesterday) }&lt;br /&gt;
    it 'returns active notifications' do&lt;br /&gt;
      expect(Notification.active_notifications).to include(active_notification)&lt;br /&gt;
      expect(Notification.active_notifications).not_to include(expired_notification)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Controller Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Test all CRUD operations for the Notifications controller to ensure endpoints function as expected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Index Action:&lt;br /&gt;
** Ensure all notifications for a given user are returned.&lt;br /&gt;
** Verify that unauthorized users cannot access the endpoint.&lt;br /&gt;
** Test paginated responses if applicable.&lt;br /&gt;
* Show Action:&lt;br /&gt;
** Ensure notifications can be retrieved by id.&lt;br /&gt;
** Handle cases where id is invalid or unauthorized.&lt;br /&gt;
* Create Action:&lt;br /&gt;
** Validate successful creation of notifications with proper attributes.&lt;br /&gt;
** Handle validation failures and unauthorized access.&lt;br /&gt;
* Update Action:&lt;br /&gt;
** Test updates to notification attributes.&lt;br /&gt;
** Ensure unauthorized users cannot perform updates.&lt;br /&gt;
* Delete Action:&lt;br /&gt;
** Verify notifications are deleted successfully.&lt;br /&gt;
** Test behavior when id is invalid or unauthorized.&lt;br /&gt;
&lt;br /&gt;
 require 'rails_helper'&lt;br /&gt;
 RSpec.describe Api::V1::NotificationsController, type: :controller do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let(:notification) { create(:notification) }&lt;br /&gt;
  describe 'GET #index' do&lt;br /&gt;
    before { sign_in admin }&lt;br /&gt;
    it 'returns notifications for the current user' do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:ok)&lt;br /&gt;
      expect(json_response).to include(notification)&lt;br /&gt;
    end&lt;br /&gt;
    it 'denies access to unauthorized users' do&lt;br /&gt;
      sign_out admin&lt;br /&gt;
      sign_in student&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:forbidden)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  describe 'POST #create' do&lt;br /&gt;
    context 'with valid attributes' do&lt;br /&gt;
      it 'creates a new notification' do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { notification: attributes_for(:notification) }&lt;br /&gt;
        }.to change(Notification, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'with invalid attributes' do&lt;br /&gt;
      it 'returns validation errors' do&lt;br /&gt;
        post :create, params: { notification: { subject: '' } }&lt;br /&gt;
        expect(response).to have_http_status(:unprocessable_entity)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''3. Integration Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure seamless interaction between models, controllers, and role-based access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Role-Based Access:&lt;br /&gt;
** Verify only authorized roles (e.g., Admin, Instructor) can manage notifications.&lt;br /&gt;
** Ensure students can only view notifications for their enrolled courses.&lt;br /&gt;
* Full CRUD Workflow:&lt;br /&gt;
** Test end-to-end creation, updating, and deletion of notifications.&lt;br /&gt;
* Error Scenarios:&lt;br /&gt;
** Handle cases where a notification is created for a non-existent course or user.&lt;br /&gt;
** Verify appropriate error messages for unauthorized actions.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications Integration', type: :request do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let!(:notification) { create(:notification, user: admin) }&lt;br /&gt;
  it 'allows admins to create notifications' do&lt;br /&gt;
    sign_in admin&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:created)&lt;br /&gt;
  end&lt;br /&gt;
  it 'prevents students from creating notifications' do&lt;br /&gt;
    sign_in student&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:forbidden)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''4. API Documentation and Testing with RSwag'''&lt;br /&gt;
&lt;br /&gt;
Goal: Generate API documentation and test all endpoints.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get 'Retrieve notifications' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      response '200', 'success' do&lt;br /&gt;
        schema type: :array, items: { type: :object, properties: { id: { type: :integer }, subject: { type: :string } } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    post 'Create a notification' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: 'date' },&lt;br /&gt;
          is_active: { type: :boolean }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject description expiration_date]&lt;br /&gt;
      }&lt;br /&gt;
      response '201', 'created' do&lt;br /&gt;
        let(:notification) { { subject: 'Test', description: 'Test notification', expiration_date: '2024-12-31', is_active: true } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160659</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160659"/>
		<updated>2024-12-04T04:35:34Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* New Files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
class Notification &amp;lt; ApplicationRecord&lt;br /&gt;
  # Associations&lt;br /&gt;
  belongs_to :course, foreign_key: :course_name, primary_key: :name&lt;br /&gt;
  belongs_to :user&lt;br /&gt;
&lt;br /&gt;
  # Validations&lt;br /&gt;
  validates :subject, presence: true, length: { maximum: 255 }&lt;br /&gt;
  validates :description, presence: true&lt;br /&gt;
  validates :expiration_date, presence: true&lt;br /&gt;
  validate :expiration_date_cannot_be_in_the_past&lt;br /&gt;
&lt;br /&gt;
  # Scopes&lt;br /&gt;
  scope :active, -&amp;gt; { where(active_flag: true) }&lt;br /&gt;
  scope :expired, -&amp;gt; { where('expiration_date &amp;lt; ?', Date.today) }&lt;br /&gt;
  scope :unread_by, -&amp;gt;(user) {&lt;br /&gt;
    joins(:course).where(courses: { id: user.assignments.pluck(:course_id) }).where(active_flag: true)&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  # Custom Validation for Expiration Date&lt;br /&gt;
  def expiration_date_cannot_be_in_the_past&lt;br /&gt;
    if expiration_date.present? &amp;amp;&amp;amp; expiration_date &amp;lt; Date.today&lt;br /&gt;
      errors.add(:expiration_date, &amp;quot;cannot be in the past&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Singleton Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Managing a global notification scheduler or manager, ensuring that only one instance exists.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Singleton Pattern ensures that there is only one centralized manager for handling notification-related tasks, such as scheduling or batch operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;4. Chain of Responsibility Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Modularizing the validation logic for notifications (e.g., checking permissions, validating expiration dates, ensuring uniqueness).&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Chain of Responsibility Pattern allows you to break down validation or processing logic into discrete steps, improving code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Following are the some of the SOLID principles with how they will be applied to the back-end development:&amp;lt;/b&amp;gt;&lt;br /&gt;
* Single Responsibility : Controllers handle HTTP requests, models handle data, and service objects handle business logic (e.g., sending notifications).&lt;br /&gt;
* Open/Closed : Extend functionality (e.g., new notification types or filters) by adding new classes or methods without modifying existing code.&lt;br /&gt;
* Interface Segregation : Create small, role-specific interfaces (e.g., policies for TAs, students, instructors) and separate service objects for different types of notifications.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
This section outlines the comprehensive testing approach for the Notifications feature to ensure it meets functional and non-functional requirements. The strategy includes detailed test cases for models, controllers, role-based access, and error handling, leveraging RSpec for testing and RSwag for API documentation.&lt;br /&gt;
&lt;br /&gt;
'''1. Unit Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure that the Notification model functions as expected by validating its attributes, associations, and methods.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
* Validations:&lt;br /&gt;
** Presence validation for subject, description, expiration_date, course_id, and user_id.&lt;br /&gt;
** Length constraints on subject and description.&lt;br /&gt;
** Format validation for expiration_date.&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :user and belongs_to :course associations are correctly established.&lt;br /&gt;
** Notifications have appropriate relationships with Course and User models.&lt;br /&gt;
&lt;br /&gt;
* Custom Methods and Scopes:&lt;br /&gt;
** active_notifications: Ensure only active notifications are returned.&lt;br /&gt;
** unread_notifications: Validate that unread notifications are fetched correctly.&lt;br /&gt;
&lt;br /&gt;
* Edge Cases:&lt;br /&gt;
** Notifications with an expired expiration_date should not appear in the active notifications list.&lt;br /&gt;
** Handling invalid foreign keys for user_id and course_id.&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe Notification, type: :model do&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it { should validate_presence_of(:subject) }&lt;br /&gt;
    it { should validate_presence_of(:description) }&lt;br /&gt;
    it { should validate_presence_of(:expiration_date) }&lt;br /&gt;
    it { should validate_length_of(:subject).is_at_most(100) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it { should belong_to(:user) }&lt;br /&gt;
    it { should belong_to(:course) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    let!(:active_notification) { create(:notification, is_active: true) }&lt;br /&gt;
    let!(:expired_notification) { create(:notification, expiration_date: Date.yesterday) }&lt;br /&gt;
    it 'returns active notifications' do&lt;br /&gt;
      expect(Notification.active_notifications).to include(active_notification)&lt;br /&gt;
      expect(Notification.active_notifications).not_to include(expired_notification)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Controller Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Test all CRUD operations for the Notifications controller to ensure endpoints function as expected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Index Action:&lt;br /&gt;
** Ensure all notifications for a given user are returned.&lt;br /&gt;
** Verify that unauthorized users cannot access the endpoint.&lt;br /&gt;
** Test paginated responses if applicable.&lt;br /&gt;
* Show Action:&lt;br /&gt;
** Ensure notifications can be retrieved by id.&lt;br /&gt;
** Handle cases where id is invalid or unauthorized.&lt;br /&gt;
* Create Action:&lt;br /&gt;
** Validate successful creation of notifications with proper attributes.&lt;br /&gt;
** Handle validation failures and unauthorized access.&lt;br /&gt;
* Update Action:&lt;br /&gt;
** Test updates to notification attributes.&lt;br /&gt;
** Ensure unauthorized users cannot perform updates.&lt;br /&gt;
* Delete Action:&lt;br /&gt;
** Verify notifications are deleted successfully.&lt;br /&gt;
** Test behavior when id is invalid or unauthorized.&lt;br /&gt;
&lt;br /&gt;
 require 'rails_helper'&lt;br /&gt;
 RSpec.describe Api::V1::NotificationsController, type: :controller do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let(:notification) { create(:notification) }&lt;br /&gt;
  describe 'GET #index' do&lt;br /&gt;
    before { sign_in admin }&lt;br /&gt;
    it 'returns notifications for the current user' do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:ok)&lt;br /&gt;
      expect(json_response).to include(notification)&lt;br /&gt;
    end&lt;br /&gt;
    it 'denies access to unauthorized users' do&lt;br /&gt;
      sign_out admin&lt;br /&gt;
      sign_in student&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:forbidden)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  describe 'POST #create' do&lt;br /&gt;
    context 'with valid attributes' do&lt;br /&gt;
      it 'creates a new notification' do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { notification: attributes_for(:notification) }&lt;br /&gt;
        }.to change(Notification, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'with invalid attributes' do&lt;br /&gt;
      it 'returns validation errors' do&lt;br /&gt;
        post :create, params: { notification: { subject: '' } }&lt;br /&gt;
        expect(response).to have_http_status(:unprocessable_entity)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''3. Integration Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure seamless interaction between models, controllers, and role-based access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Role-Based Access:&lt;br /&gt;
** Verify only authorized roles (e.g., Admin, Instructor) can manage notifications.&lt;br /&gt;
** Ensure students can only view notifications for their enrolled courses.&lt;br /&gt;
* Full CRUD Workflow:&lt;br /&gt;
** Test end-to-end creation, updating, and deletion of notifications.&lt;br /&gt;
* Error Scenarios:&lt;br /&gt;
** Handle cases where a notification is created for a non-existent course or user.&lt;br /&gt;
** Verify appropriate error messages for unauthorized actions.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications Integration', type: :request do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let!(:notification) { create(:notification, user: admin) }&lt;br /&gt;
  it 'allows admins to create notifications' do&lt;br /&gt;
    sign_in admin&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:created)&lt;br /&gt;
  end&lt;br /&gt;
  it 'prevents students from creating notifications' do&lt;br /&gt;
    sign_in student&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:forbidden)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''4. API Documentation and Testing with RSwag'''&lt;br /&gt;
&lt;br /&gt;
Goal: Generate API documentation and test all endpoints.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get 'Retrieve notifications' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      response '200', 'success' do&lt;br /&gt;
        schema type: :array, items: { type: :object, properties: { id: { type: :integer }, subject: { type: :string } } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    post 'Create a notification' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: 'date' },&lt;br /&gt;
          is_active: { type: :boolean }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject description expiration_date]&lt;br /&gt;
      }&lt;br /&gt;
      response '201', 'created' do&lt;br /&gt;
        let(:notification) { { subject: 'Test', description: 'Test notification', expiration_date: '2024-12-31', is_active: true } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160656</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=160656"/>
		<updated>2024-12-04T04:33:23Z</updated>

		<summary type="html">&lt;p&gt;Akilled: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== New Files ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Singleton Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Managing a global notification scheduler or manager, ensuring that only one instance exists.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Singleton Pattern ensures that there is only one centralized manager for handling notification-related tasks, such as scheduling or batch operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;4. Chain of Responsibility Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Modularizing the validation logic for notifications (e.g., checking permissions, validating expiration dates, ensuring uniqueness).&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Chain of Responsibility Pattern allows you to break down validation or processing logic into discrete steps, improving code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Following are the some of the SOLID principles with how they will be applied to the back-end development:&amp;lt;/b&amp;gt;&lt;br /&gt;
* Single Responsibility : Controllers handle HTTP requests, models handle data, and service objects handle business logic (e.g., sending notifications).&lt;br /&gt;
* Open/Closed : Extend functionality (e.g., new notification types or filters) by adding new classes or methods without modifying existing code.&lt;br /&gt;
* Interface Segregation : Create small, role-specific interfaces (e.g., policies for TAs, students, instructors) and separate service objects for different types of notifications.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
This section outlines the comprehensive testing approach for the Notifications feature to ensure it meets functional and non-functional requirements. The strategy includes detailed test cases for models, controllers, role-based access, and error handling, leveraging RSpec for testing and RSwag for API documentation.&lt;br /&gt;
&lt;br /&gt;
'''1. Unit Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure that the Notification model functions as expected by validating its attributes, associations, and methods.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
* Validations:&lt;br /&gt;
** Presence validation for subject, description, expiration_date, course_id, and user_id.&lt;br /&gt;
** Length constraints on subject and description.&lt;br /&gt;
** Format validation for expiration_date.&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :user and belongs_to :course associations are correctly established.&lt;br /&gt;
** Notifications have appropriate relationships with Course and User models.&lt;br /&gt;
&lt;br /&gt;
* Custom Methods and Scopes:&lt;br /&gt;
** active_notifications: Ensure only active notifications are returned.&lt;br /&gt;
** unread_notifications: Validate that unread notifications are fetched correctly.&lt;br /&gt;
&lt;br /&gt;
* Edge Cases:&lt;br /&gt;
** Notifications with an expired expiration_date should not appear in the active notifications list.&lt;br /&gt;
** Handling invalid foreign keys for user_id and course_id.&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe Notification, type: :model do&lt;br /&gt;
  describe 'validations' do&lt;br /&gt;
    it { should validate_presence_of(:subject) }&lt;br /&gt;
    it { should validate_presence_of(:description) }&lt;br /&gt;
    it { should validate_presence_of(:expiration_date) }&lt;br /&gt;
    it { should validate_length_of(:subject).is_at_most(100) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'associations' do&lt;br /&gt;
    it { should belong_to(:user) }&lt;br /&gt;
    it { should belong_to(:course) }&lt;br /&gt;
  end&lt;br /&gt;
  describe 'scopes' do&lt;br /&gt;
    let!(:active_notification) { create(:notification, is_active: true) }&lt;br /&gt;
    let!(:expired_notification) { create(:notification, expiration_date: Date.yesterday) }&lt;br /&gt;
    it 'returns active notifications' do&lt;br /&gt;
      expect(Notification.active_notifications).to include(active_notification)&lt;br /&gt;
      expect(Notification.active_notifications).not_to include(expired_notification)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Controller Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Test all CRUD operations for the Notifications controller to ensure endpoints function as expected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Index Action:&lt;br /&gt;
** Ensure all notifications for a given user are returned.&lt;br /&gt;
** Verify that unauthorized users cannot access the endpoint.&lt;br /&gt;
** Test paginated responses if applicable.&lt;br /&gt;
* Show Action:&lt;br /&gt;
** Ensure notifications can be retrieved by id.&lt;br /&gt;
** Handle cases where id is invalid or unauthorized.&lt;br /&gt;
* Create Action:&lt;br /&gt;
** Validate successful creation of notifications with proper attributes.&lt;br /&gt;
** Handle validation failures and unauthorized access.&lt;br /&gt;
* Update Action:&lt;br /&gt;
** Test updates to notification attributes.&lt;br /&gt;
** Ensure unauthorized users cannot perform updates.&lt;br /&gt;
* Delete Action:&lt;br /&gt;
** Verify notifications are deleted successfully.&lt;br /&gt;
** Test behavior when id is invalid or unauthorized.&lt;br /&gt;
&lt;br /&gt;
 require 'rails_helper'&lt;br /&gt;
 RSpec.describe Api::V1::NotificationsController, type: :controller do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let(:notification) { create(:notification) }&lt;br /&gt;
  describe 'GET #index' do&lt;br /&gt;
    before { sign_in admin }&lt;br /&gt;
    it 'returns notifications for the current user' do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:ok)&lt;br /&gt;
      expect(json_response).to include(notification)&lt;br /&gt;
    end&lt;br /&gt;
    it 'denies access to unauthorized users' do&lt;br /&gt;
      sign_out admin&lt;br /&gt;
      sign_in student&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to have_http_status(:forbidden)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  describe 'POST #create' do&lt;br /&gt;
    context 'with valid attributes' do&lt;br /&gt;
      it 'creates a new notification' do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { notification: attributes_for(:notification) }&lt;br /&gt;
        }.to change(Notification, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'with invalid attributes' do&lt;br /&gt;
      it 'returns validation errors' do&lt;br /&gt;
        post :create, params: { notification: { subject: '' } }&lt;br /&gt;
        expect(response).to have_http_status(:unprocessable_entity)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''3. Integration Testing'''&lt;br /&gt;
&lt;br /&gt;
Goal: Ensure seamless interaction between models, controllers, and role-based access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Key Test Cases:&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Role-Based Access:&lt;br /&gt;
** Verify only authorized roles (e.g., Admin, Instructor) can manage notifications.&lt;br /&gt;
** Ensure students can only view notifications for their enrolled courses.&lt;br /&gt;
* Full CRUD Workflow:&lt;br /&gt;
** Test end-to-end creation, updating, and deletion of notifications.&lt;br /&gt;
* Error Scenarios:&lt;br /&gt;
** Handle cases where a notification is created for a non-existent course or user.&lt;br /&gt;
** Verify appropriate error messages for unauthorized actions.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications Integration', type: :request do&lt;br /&gt;
  let(:admin) { create(:user, role: 'Admin') }&lt;br /&gt;
  let(:student) { create(:user, role: 'Student') }&lt;br /&gt;
  let!(:notification) { create(:notification, user: admin) }&lt;br /&gt;
  it 'allows admins to create notifications' do&lt;br /&gt;
    sign_in admin&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:created)&lt;br /&gt;
  end&lt;br /&gt;
  it 'prevents students from creating notifications' do&lt;br /&gt;
    sign_in student&lt;br /&gt;
    post '/api/v1/notifications', params: { notification: attributes_for(:notification) }&lt;br /&gt;
    expect(response).to have_http_status(:forbidden)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''4. API Documentation and Testing with RSwag'''&lt;br /&gt;
&lt;br /&gt;
Goal: Generate API documentation and test all endpoints.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Notifications API', type: :request do&lt;br /&gt;
  path '/api/v1/notifications' do&lt;br /&gt;
    get 'Retrieve notifications' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      response '200', 'success' do&lt;br /&gt;
        schema type: :array, items: { type: :object, properties: { id: { type: :integer }, subject: { type: :string } } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    post 'Create a notification' do&lt;br /&gt;
      tags 'Notifications'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      parameter name: :notification, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          subject: { type: :string },&lt;br /&gt;
          description: { type: :string },&lt;br /&gt;
          expiration_date: { type: :string, format: 'date' },&lt;br /&gt;
          is_active: { type: :boolean }&lt;br /&gt;
        },&lt;br /&gt;
        required: %w[subject description expiration_date]&lt;br /&gt;
      }&lt;br /&gt;
      response '201', 'created' do&lt;br /&gt;
        let(:notification) { { subject: 'Test', description: 'Test notification', expiration_date: '2024-12-31', is_active: true } }&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=159637</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=159637"/>
		<updated>2024-11-17T22:43:29Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* Objective */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The objective was to create a Notification model in the backend to handle notifications for the Expertiza system. &lt;br /&gt;
&lt;br /&gt;
This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. &lt;br /&gt;
Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
The main objective is to create the Notification controller and model to handle sending and receiving notifications on the Expertiza platform.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Observer Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Automatically notify users (e.g., students enrolled in a course) whenever a new notification is created or updated.&lt;br /&gt;
** This ensures users are always informed about important updates without requiring manual intervention.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Notification model acts as the subject, and the students (or their respective notification systems) are observers.&lt;br /&gt;
** When a notification is created or updated, all observers are automatically notified through an after_commit callback.&lt;br /&gt;
** This pattern decouples the logic for creating notifications from the logic for notifying users, making the system easier to maintain and extend.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Factory Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Creating different types of notifications (e.g., course notifications, system notifications, global announcements) with varying attributes or behaviors.&lt;br /&gt;
** This centralizes the creation logic and ensures consistency in object instantiation.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The factory centralizes the creation logic, making it easy to add new notification types in the future.&lt;br /&gt;
** It also reduces clutter in the controller by abstracting the instantiation process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;4. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;5. Command Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Encapsulating the logic for sending notifications (e.g., emails, in-app alerts) into discrete, reusable objects.&lt;br /&gt;
** Useful for task queuing or asynchronous operations.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Command Pattern encapsulates the logic for sending notifications, making it easier to queue or log these operations.&lt;br /&gt;
** It improves code reusability and separation of concerns.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;6. Template Method Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Defining a common process for creating notifications while allowing specific steps to be overridden for different types of notifications (e.g., course notifications vs. global announcements).&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Template Method Pattern enforces a consistent process for creating notifications while allowing flexibility for specific steps.&lt;br /&gt;
** This ensures uniformity across different notification types.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;7. Singleton Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Managing a global notification scheduler or manager, ensuring that only one instance exists.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Singleton Pattern ensures that there is only one centralized manager for handling notification-related tasks, such as scheduling or batch operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;8. Chain of Responsibility Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Modularizing the validation logic for notifications (e.g., checking permissions, validating expiration dates, ensuring uniqueness).&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Chain of Responsibility Pattern allows you to break down validation or processing logic into discrete steps, improving code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
1. Model Tests:&lt;br /&gt;
&lt;br /&gt;
* Validate presence and format of subject and description.&lt;br /&gt;
* Test is_active and is_unread default values.&lt;br /&gt;
&lt;br /&gt;
2. Controller Tests:&lt;br /&gt;
&lt;br /&gt;
* Ensure proper creation, update, and deletion of notifications.&lt;br /&gt;
* Test that only authorized users can manage notifications.&lt;br /&gt;
&lt;br /&gt;
3. Integration Tests:&lt;br /&gt;
&lt;br /&gt;
* Test access control to verify that only eligible users can view or manage notifications based on role and course association.&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=159636</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=159636"/>
		<updated>2024-11-17T22:41:18Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* Details about the Notification Model and Controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
The Notification model in Expertiza serves a critical role in enhancing communication and user engagement on the platform. It is essential because it automates the process of alerting users to significant events, such as receiving feedback, team changes, or assignment updates, without requiring users to actively seek out this information. By streamlining these updates, the model reduces the risk of missed information, helping users stay on top of their responsibilities, collaborate more effectively, and respond in a timely manner. This function is particularly valuable in a platform like Expertiza, where users juggle multiple assignments, peer reviews, and team interactions, and would otherwise need to manually monitor changes and updates or rely on external tools for reminders.&lt;br /&gt;
&lt;br /&gt;
The Notification model also improves the overall user experience by organizing and presenting notifications in a way that makes them easy to access and track. It stores notification details (like type, content, and timestamp) and associates them with specific users, ensuring each user receives personalized, relevant updates. Users can view notifications sorted by date or filtered by read/unread status, making it easier to prioritize tasks and responses. Ultimately, the Notification model supports Expertiza’s usability by helping users stay informed and accountable, contributing to an environment that encourages active participation and smooth collaboration across assignments.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
To create a Notification model in the backend to handle notifications for the Expertiza system. This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Observer Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Automatically notify users (e.g., students enrolled in a course) whenever a new notification is created or updated.&lt;br /&gt;
** This ensures users are always informed about important updates without requiring manual intervention.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Notification model acts as the subject, and the students (or their respective notification systems) are observers.&lt;br /&gt;
** When a notification is created or updated, all observers are automatically notified through an after_commit callback.&lt;br /&gt;
** This pattern decouples the logic for creating notifications from the logic for notifying users, making the system easier to maintain and extend.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Factory Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Creating different types of notifications (e.g., course notifications, system notifications, global announcements) with varying attributes or behaviors.&lt;br /&gt;
** This centralizes the creation logic and ensures consistency in object instantiation.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The factory centralizes the creation logic, making it easy to add new notification types in the future.&lt;br /&gt;
** It also reduces clutter in the controller by abstracting the instantiation process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;4. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;5. Command Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Encapsulating the logic for sending notifications (e.g., emails, in-app alerts) into discrete, reusable objects.&lt;br /&gt;
** Useful for task queuing or asynchronous operations.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Command Pattern encapsulates the logic for sending notifications, making it easier to queue or log these operations.&lt;br /&gt;
** It improves code reusability and separation of concerns.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;6. Template Method Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Defining a common process for creating notifications while allowing specific steps to be overridden for different types of notifications (e.g., course notifications vs. global announcements).&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Template Method Pattern enforces a consistent process for creating notifications while allowing flexibility for specific steps.&lt;br /&gt;
** This ensures uniformity across different notification types.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;7. Singleton Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Managing a global notification scheduler or manager, ensuring that only one instance exists.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Singleton Pattern ensures that there is only one centralized manager for handling notification-related tasks, such as scheduling or batch operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;8. Chain of Responsibility Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Modularizing the validation logic for notifications (e.g., checking permissions, validating expiration dates, ensuring uniqueness).&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Chain of Responsibility Pattern allows you to break down validation or processing logic into discrete steps, improving code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
1. Model Tests:&lt;br /&gt;
&lt;br /&gt;
* Validate presence and format of subject and description.&lt;br /&gt;
* Test is_active and is_unread default values.&lt;br /&gt;
&lt;br /&gt;
2. Controller Tests:&lt;br /&gt;
&lt;br /&gt;
* Ensure proper creation, update, and deletion of notifications.&lt;br /&gt;
* Test that only authorized users can manage notifications.&lt;br /&gt;
&lt;br /&gt;
3. Integration Tests:&lt;br /&gt;
&lt;br /&gt;
* Test access control to verify that only eligible users can view or manage notifications based on role and course association.&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=159635</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=159635"/>
		<updated>2024-11-17T22:31:33Z</updated>

		<summary type="html">&lt;p&gt;Akilled: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Details about the Notification Model and Controller==&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
To create a Notification model in the backend to handle notifications for the Expertiza system. This model will manage notifications for different courses and be accessible to students and instructors based on their association with a course. Notifications can have attributes such as subject, description, expiration date, and status (active/inactive).&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic: Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
&amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
1. Model Creation:&lt;br /&gt;
&lt;br /&gt;
Create a Notification model with the following key attributes:&lt;br /&gt;
* id: Primary key (auto-generated).&lt;br /&gt;
* subject: Brief title of the notification.&lt;br /&gt;
* description: Detailed message of the notification.&lt;br /&gt;
* expiration_date: The date when the notification should expire.&lt;br /&gt;
* is_active: Boolean flag to mark if the notification is active or inactive.&lt;br /&gt;
* is_unread: Boolean to mark if a notification is unread (default to true for new notifications).&lt;br /&gt;
&lt;br /&gt;
2. Associations:&lt;br /&gt;
&lt;br /&gt;
* Define associations between Notification, User, and Course models.&lt;br /&gt;
* User Association: Each notification should have a creator (e.g., a teaching assistant or instructor).&lt;br /&gt;
* Course Association: Each notification should be linked to a course, and the enrolled students should be able to view relevant notifications.&lt;br /&gt;
&lt;br /&gt;
3. Relationships:&lt;br /&gt;
&lt;br /&gt;
* One-to-Many: Course to Notification, as each course can have multiple notifications.&lt;br /&gt;
* One-to-Many: User (creator) to Notification, as a user can create multiple notifications.&lt;br /&gt;
* Many-to-Many (indirect): User to Notification via course enrollment, as multiple students can view a notification if they are enrolled in the course associated with the notification.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
[[File:Schema2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
===Associations===&lt;br /&gt;
&lt;br /&gt;
'''Notification'''&lt;br /&gt;
&lt;br /&gt;
* belongs_to :user - Links the notification to its creator (TA, instructor).&lt;br /&gt;
&lt;br /&gt;
* belongs_to :course - Links the notification to a course.&lt;br /&gt;
&lt;br /&gt;
'''User'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Users (instructors, TAs) can create multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :viewable_notifications, through: :courses - Students can view notifications for courses they are enrolled in.&lt;br /&gt;
&lt;br /&gt;
'''Course'''&lt;br /&gt;
&lt;br /&gt;
* has_many :notifications - Each course can have multiple notifications.&lt;br /&gt;
&lt;br /&gt;
* has_many :students, through: :enrollments - Defines which students are associated with the course.&lt;br /&gt;
&lt;br /&gt;
==UML Diagram==&lt;br /&gt;
[[File:UML notification2.PNG| center]]&lt;br /&gt;
&lt;br /&gt;
''' Relationship Explanation''' &lt;br /&gt;
&lt;br /&gt;
* User to Notification: A User (e.g., TA, instructor) can create multiple notifications.&lt;br /&gt;
* Course to Notification: Each Course can have multiple notifications associated with it.&lt;br /&gt;
* User (Student) to Notification (Viewer): Through Course enrollment, students can access notifications related to their courses.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&amp;lt;b&amp;gt;NotificationController Implementation&amp;lt;/b&amp;gt;: Following are the controller methods:&lt;br /&gt;
&lt;br /&gt;
1. create:&lt;br /&gt;
&lt;br /&gt;
* Description: This method is responsible for creating a new notification. It validates the incoming data to ensure that all required fields are present and correctly formatted. Only authorized users (instructors or TAs) can create notifications. Upon successful creation, the method associates the notification with the specified course and user (creator).&lt;br /&gt;
* API Endpoint: POST /notifications&lt;br /&gt;
* Parameters:&lt;br /&gt;
** subject (required): The title of the notification that briefly describes its purpose (limited to 255 characters).&lt;br /&gt;
** description (optional): Detailed content of the notification.&lt;br /&gt;
** expiration_date (optional): The date until which the notification remains valid. Defaults to no expiration.&lt;br /&gt;
** is_active (optional): A boolean flag indicating if the notification is active (default is true).&lt;br /&gt;
** course_id (required): The course associated with the notification.&lt;br /&gt;
* Authorization: Ensures that only users with roles of TA or instructor can create a notification.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the newly created notification with a 201 status.&lt;br /&gt;
** Error: Returns validation errors (e.g., missing fields, invalid data) with a 422 status.&lt;br /&gt;
&lt;br /&gt;
2. index:&lt;br /&gt;
&lt;br /&gt;
* Description: The index method retrieves a list of notifications based on specific filters, such as active status, unread status, or course association. This endpoint ensures that students only see notifications related to the courses they are enrolled in. It supports querying with multiple optional parameters for flexibility.&lt;br /&gt;
* API Endpoint: GET /notifications&lt;br /&gt;
* Parameters: Query parameters (optional):&lt;br /&gt;
** is_active: Filter notifications by their active status.&lt;br /&gt;
** is_unread: Retrieve only unread notifications for the current user.&lt;br /&gt;
** course_id: Fetch notifications specific to a course.&lt;br /&gt;
* Authorization: Students can only access notifications for courses they are enrolled in. Instructors and TAs can view all notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns an array of filtered notifications with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
3. show:&lt;br /&gt;
&lt;br /&gt;
* Description: This method retrieves the details of a specific notification identified by its unique ID. It ensures that the current user is authorized to view the notification (e.g., enrolled in the course or the creator of the notification).&lt;br /&gt;
* API Endpoint: GET /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be retrieved.&lt;br /&gt;
* Authorization: Students can view notifications for courses they are enrolled in. Instructors and TAs can view notifications they have created.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the notification details with a 200 status.&lt;br /&gt;
** Error: Returns a 404 status if the notification is not found or the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
4. update:&lt;br /&gt;
&lt;br /&gt;
* Description: This method allows the creator of a notification (TA or instructor) to update its details. It validates the incoming data and ensures that the user is authorized to make changes.&lt;br /&gt;
* API Endpoint: PUT /notifications/:id&lt;br /&gt;
* Parameters: Fields that can be updated include subject, description, expiration_date, and is_active.&lt;br /&gt;
* Authorization: Only the creator of the notification can update it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if the user does not have the required permissions.&lt;br /&gt;
&lt;br /&gt;
5. destroy:&lt;br /&gt;
&lt;br /&gt;
* Description: This method deletes a specific notification. Only the user who created the notification can perform this action. The method ensures that no unauthorized users can delete notifications.&lt;br /&gt;
* API Endpoint: DELETE /notifications/:id&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be deleted.&lt;br /&gt;
* Authorization: Only the creator of the notification can delete it.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns a 204 status with no content upon successful deletion.&lt;br /&gt;
** Error: Returns a 403 status if the user is unauthorized.&lt;br /&gt;
&lt;br /&gt;
6. toggle_notification_visibility:&lt;br /&gt;
&lt;br /&gt;
* Description: This method toggles the is_active status of a notification. For example, a TA or instructor can deactivate a notification that is no longer relevant. The method ensures that only the creator of the notification can perform this action.&lt;br /&gt;
* API Endpoint: PATCH /notifications/:id/toggle&lt;br /&gt;
* Parameters:&lt;br /&gt;
** id: The unique identifier of the notification to be toggled.&lt;br /&gt;
* Authorization: Only the creator of the notification can toggle its visibility.&lt;br /&gt;
* Response:&lt;br /&gt;
** Success: Returns the updated notification status with a 200 status.&lt;br /&gt;
** Error: Returns a 403 status if unauthorized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Model Implementation&amp;lt;/b&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
1. Notification model:&lt;br /&gt;
&lt;br /&gt;
* Description: The Notification model represents a single notification. It includes all attributes, validations, and associations necessary for managing notifications.&lt;br /&gt;
* Attributes:&lt;br /&gt;
** subject: The title of the notification (required, max length: 255).&lt;br /&gt;
** description: The detailed content of the notification.&lt;br /&gt;
** expiration_date: The date when the notification should expire (validated to be in the future).&lt;br /&gt;
** is_active: Indicates whether the notification is active (default: true).&lt;br /&gt;
** is_unread: Marks if a notification is unread (default: true).&lt;br /&gt;
** course_id: Links the notification to a course.&lt;br /&gt;
** user_id: Links the notification to its creator.&lt;br /&gt;
* Associations:&lt;br /&gt;
** belongs_to :course&lt;br /&gt;
** belongs_to :user&lt;br /&gt;
* Validations:&lt;br /&gt;
** Ensures the presence of subject, course_id, and user_id.&lt;br /&gt;
** Validates expiration_date to ensure it is not in the past.&lt;br /&gt;
* Scopes:&lt;br /&gt;
** active: Filters notifications that are active.&lt;br /&gt;
** unread: Filters unread notifications for a user.&lt;br /&gt;
&lt;br /&gt;
2. User Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications (creator role).&lt;br /&gt;
** has_many :viewable_notifications, through: :courses (student role).&lt;br /&gt;
&lt;br /&gt;
3. Course Model:&lt;br /&gt;
&lt;br /&gt;
* Associations:&lt;br /&gt;
** has_many :notifications.&lt;br /&gt;
** has_many :students, through: :enrollments.&lt;br /&gt;
&lt;br /&gt;
== Endpoints for Notification Management ==&lt;br /&gt;
&lt;br /&gt;
Endpoints for Creating, Reading, Updating, and Deleting (CRUD) Notifications&lt;br /&gt;
&lt;br /&gt;
1. POST /notifications - Create a new notification. The create method in the NotificationController implementation aligns with this endpoint, allowing authorized users to create notifications for specific courses.&lt;br /&gt;
&lt;br /&gt;
2. GET /notifications - Get a list of notifications (with optional filters, such as is_active or is_unread). The index method aligns with this endpoint, allowing filtered retrieval of notifications.&lt;br /&gt;
&lt;br /&gt;
3. GET /notifications/:id - View details of a specific notification. The show method aligns with this endpoint, retrieving specific notification details.&lt;br /&gt;
&lt;br /&gt;
4. PUT /notifications/:id - Update a specific notification. The update method allows modification of existing notifications, respecting role-based access.&lt;br /&gt;
&lt;br /&gt;
5. DELETE /notifications/:id - Delete a specific notification. The destroy method aligns with this endpoint, enabling notification deletion by authorized users.&lt;br /&gt;
&lt;br /&gt;
6. PATCH /notifications/:id/toggle - Toggle active state of a notification. The toggle_notification_visibility method handles this functionality, toggling the is_active flag.&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Observer Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Automatically notify users (e.g., students enrolled in a course) whenever a new notification is created or updated.&lt;br /&gt;
** This ensures users are always informed about important updates without requiring manual intervention.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Notification model acts as the subject, and the students (or their respective notification systems) are observers.&lt;br /&gt;
** When a notification is created or updated, all observers are automatically notified through an after_commit callback.&lt;br /&gt;
** This pattern decouples the logic for creating notifications from the logic for notifying users, making the system easier to maintain and extend.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Factory Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Creating different types of notifications (e.g., course notifications, system notifications, global announcements) with varying attributes or behaviors.&lt;br /&gt;
** This centralizes the creation logic and ensures consistency in object instantiation.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The factory centralizes the creation logic, making it easy to add new notification types in the future.&lt;br /&gt;
** It also reduces clutter in the controller by abstracting the instantiation process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Strategy Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically applying different filtering criteria for notifications (e.g., active notifications, unread notifications, notifications for a specific course).&lt;br /&gt;
** This modularizes the filtering logic, making it easier to extend or change in the future.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Strategy Pattern separates filtering logic into individual strategy classes, making it easy to add new filters without modifying existing code.&lt;br /&gt;
** It also enhances the maintainability and testability of the system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;4. Decorator Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Dynamically modifying the presentation of notifications based on user roles or other conditions.&lt;br /&gt;
** For example, students might see a simplified view of notifications, while instructors see a detailed view.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Decorator Pattern adds additional functionality (like role-based formatting) without modifying the original Notification model.&lt;br /&gt;
** It keeps the model clean and focused on core functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;5. Command Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Encapsulating the logic for sending notifications (e.g., emails, in-app alerts) into discrete, reusable objects.&lt;br /&gt;
** Useful for task queuing or asynchronous operations.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Command Pattern encapsulates the logic for sending notifications, making it easier to queue or log these operations.&lt;br /&gt;
** It improves code reusability and separation of concerns.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;6. Template Method Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Defining a common process for creating notifications while allowing specific steps to be overridden for different types of notifications (e.g., course notifications vs. global announcements).&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Template Method Pattern enforces a consistent process for creating notifications while allowing flexibility for specific steps.&lt;br /&gt;
** This ensures uniformity across different notification types.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;7. Singleton Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Managing a global notification scheduler or manager, ensuring that only one instance exists.&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Singleton Pattern ensures that there is only one centralized manager for handling notification-related tasks, such as scheduling or batch operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;8. Chain of Responsibility Pattern&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use Case:&lt;br /&gt;
** Modularizing the validation logic for notifications (e.g., checking permissions, validating expiration dates, ensuring uniqueness).&lt;br /&gt;
* Explanation:&lt;br /&gt;
** The Chain of Responsibility Pattern allows you to break down validation or processing logic into discrete steps, improving code readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
1. Model Tests:&lt;br /&gt;
&lt;br /&gt;
* Validate presence and format of subject and description.&lt;br /&gt;
* Test is_active and is_unread default values.&lt;br /&gt;
&lt;br /&gt;
2. Controller Tests:&lt;br /&gt;
&lt;br /&gt;
* Ensure proper creation, update, and deletion of notifications.&lt;br /&gt;
* Test that only authorized users can manage notifications.&lt;br /&gt;
&lt;br /&gt;
3. Integration Tests:&lt;br /&gt;
&lt;br /&gt;
* Test access control to verify that only eligible users can view or manage notifications based on role and course association.&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' [https://github.com/SoubarnicaSuresh/reimplementation-back-end reimplementation back-end]&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=158768</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=158768"/>
		<updated>2024-11-10T22:26:19Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* Design Goals */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
This project is the implementation for the notification model and controller in the Expertiza backend.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic:&lt;br /&gt;
        * Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
* &amp;lt;b&amp;gt;Implement the Notification backend:&amp;lt;/b&amp;gt; Implement the Notification in Ruby on Rails.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
* Each notification must be associated with a single course.&lt;br /&gt;
* Each course may or may not have notifications associated with it.&lt;br /&gt;
* Many notifications can be sent to many users.&lt;br /&gt;
* Many users can create/send many notifications.&lt;br /&gt;
&lt;br /&gt;
===UML Diagram===&lt;br /&gt;
&amp;lt;goes here&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&lt;br /&gt;
== ⁠issue, methods, problem, solution (rename later)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' &lt;br /&gt;
* '''Pull Request:'''&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=158767</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=158767"/>
		<updated>2024-11-10T22:22:15Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* Schema Diagram */ Reasoning behind UML Diagram&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
This project is the implementation for the notification model and controller in the Expertiza backend.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic:&lt;br /&gt;
        * Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
* &amp;lt;b&amp;gt;Modernize the Frontend:&amp;lt;/b&amp;gt; Re-implement the existing Institutions UI from Ruby on Rails to TypeScript and ReactJS for improved modularity, performance, and maintainability.&lt;br /&gt;
&lt;br /&gt;
==Schema==&lt;br /&gt;
* Each notification must be associated with a single course.&lt;br /&gt;
* Each course may or may not have notifications associated with it.&lt;br /&gt;
* Many notifications can be sent to many users.&lt;br /&gt;
* Many users can create/send many notifications.&lt;br /&gt;
&lt;br /&gt;
===UML Diagram===&lt;br /&gt;
&amp;lt;goes here&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&lt;br /&gt;
== ⁠issue, methods, problem, solution (rename later)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' &lt;br /&gt;
* '''Pull Request:'''&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=158764</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=158764"/>
		<updated>2024-11-10T22:15:00Z</updated>

		<summary type="html">&lt;p&gt;Akilled: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
This project is the implementation for the notification model and controller in the Expertiza backend.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* Create a new Notification model with appropriate attributes and relationships:&lt;br /&gt;
* Define associations with User and Course models&lt;br /&gt;
* Implement scopes for filtering notifications based on roles&lt;br /&gt;
* Add validation rules for notification data&lt;br /&gt;
* Include timestamp fields for proper notification tracking&lt;br /&gt;
* Develop a NotificationsController with:&lt;br /&gt;
    * Standard CRUD operations (create, read, update, delete)&lt;br /&gt;
    * Role-based access control logic&lt;br /&gt;
    * Course enrollment verification&lt;br /&gt;
    * Proper error handling and response formatting&lt;br /&gt;
    * RESTful API endpoints&lt;br /&gt;
    * Implement authorization logic:&lt;br /&gt;
        * Add policies to ensure students only see relevant notifications&lt;br /&gt;
* Write comprehensive test cases:&lt;br /&gt;
    * Unit tests for the Notification model&lt;br /&gt;
    * Controller tests covering all CRUD operations&lt;br /&gt;
    * Integration tests for role-based access&lt;br /&gt;
    * Test cases for error scenarios and edge cases&lt;br /&gt;
&lt;br /&gt;
==Design Goals==&lt;br /&gt;
* &amp;lt;b&amp;gt;Modernize the Frontend:&amp;lt;/b&amp;gt; Re-implement the existing Institutions UI from Ruby on Rails to TypeScript and ReactJS for improved modularity, performance, and maintainability.&lt;br /&gt;
&lt;br /&gt;
==Schema Diagram==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&lt;br /&gt;
== ⁠issue, methods, problem, solution (rename later)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' &lt;br /&gt;
* '''Pull Request:'''&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=158763</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=158763"/>
		<updated>2024-11-10T22:09:46Z</updated>

		<summary type="html">&lt;p&gt;Akilled: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
=About Expertiza=&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&lt;br /&gt;
=Design Goals=&lt;br /&gt;
* &amp;lt;b&amp;gt;Modernize the Frontend:&amp;lt;/b&amp;gt; Re-implement the existing Institutions UI from Ruby on Rails to TypeScript and ReactJS for improved modularity, performance, and maintainability.&lt;br /&gt;
&lt;br /&gt;
==Schema Diagram==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
== ⁠issue, methods, problem, solution (rename later)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
* '''Aditi Killedar''' akilled@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' &lt;br /&gt;
* '''Pull Request:'''&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=158760</id>
		<title>CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2483._Reimplement_Notification_Controller_and_Model&amp;diff=158760"/>
		<updated>2024-11-10T21:14:14Z</updated>

		<summary type="html">&lt;p&gt;Akilled: Created page with &amp;quot; __TOC__  ==Introduction==  =About Expertiza=  ==Requirements==  =Design Goals= * &amp;lt;b&amp;gt;Modernize the Frontend:&amp;lt;/b&amp;gt; Re-implement the existing Institutions UI from Ruby on Rails to TypeScript and ReactJS for improved modularity, performance, and maintainability.  ==Schema Diagram==   =Implementation=  == ⁠issue, methods, problem, solution (rename later)==   =Design Pattern=  =Testing=   =Team= &amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu  * '''Vaibhavi Shetty:''' vshetty2@n...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
=About Expertiza=&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&lt;br /&gt;
=Design Goals=&lt;br /&gt;
* &amp;lt;b&amp;gt;Modernize the Frontend:&amp;lt;/b&amp;gt; Re-implement the existing Institutions UI from Ruby on Rails to TypeScript and ReactJS for improved modularity, performance, and maintainability.&lt;br /&gt;
&lt;br /&gt;
==Schema Diagram==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
== ⁠issue, methods, problem, solution (rename later)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Design Pattern=&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor&amp;lt;/b&amp;gt; Jay Patel : jhpatel9@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
* '''Vaibhavi Shetty:''' vshetty2@ncsu.edu&lt;br /&gt;
* '''Soubarnica Suresh''' ssomang@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
* '''Github Repository:''' &lt;br /&gt;
* '''Pull Request:'''&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2463_Implement_Front_End_for_Student_Task_List&amp;diff=158012</id>
		<title>CSC/ECE 517 Fall 2024 - E2463 Implement Front End for Student Task List</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2463_Implement_Front_End_for_Student_Task_List&amp;diff=158012"/>
		<updated>2024-10-30T01:14:18Z</updated>

		<summary type="html">&lt;p&gt;Akilled: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Expertiza ==&lt;br /&gt;
Expertiza is an open-source learning management system primarily developed with Ruby on Rails. It offers features such as creating tests and assignments, managing teams and courses, and, most importantly, providing a robust framework for peer reviews and group feedback. This project focuses on developing frontend components in React, with an emphasis on the Student Task list page. The aim is to build a fully operational user interface for these components using React.js and TypeScript.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
The main objective of this project is to implement the front end for the Student Task list page within Expertiza.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
===Objective===&lt;br /&gt;
This project’s goal is to redesign the front end of the current non-TypeScript Student Task List page on Expertiza by building a new user interface with React.js and TypeScript, ensuring a more type-safe development experience. The page will showcase all assignments the user is involved in, requiring data fetching to obtain the assignment list, filtering based on the user’s participation, and presenting the results in a visually engaging, user-friendly format through React components.&lt;br /&gt;
This is the visual framework for creating the user interface:&lt;br /&gt;
&lt;br /&gt;
[[File: Flow_Chart_Student_tasks.jpg | 1000px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Development Steps===&lt;br /&gt;
*&amp;lt;u&amp;gt;Review Current Interface&amp;lt;/u&amp;gt;:  Conduct a detailed analysis of the existing Ruby on Rails UI to understand its layout and features.&lt;br /&gt;
*&amp;lt;u&amp;gt;Setup Development Environment&amp;lt;/u&amp;gt;: Configure the environment to work with TypeScript and React.&lt;br /&gt;
*&amp;lt;u&amp;gt;Design Components&amp;lt;/u&amp;gt;: Break down the UI into distinct React components, defining the props and states needed for each.&lt;br /&gt;
*&amp;lt;u&amp;gt;Implement in Typescript&amp;lt;/u&amp;gt;: Develop the component logic in TypeScript, prioritizing type safety.&lt;br /&gt;
*&amp;lt;u&amp;gt;Replicate Functionality&amp;lt;/u&amp;gt;: Ensure all features from the Rails application are mirrored in the React components, maintaining full functionality.&lt;br /&gt;
*&amp;lt;u&amp;gt;Styling and Add Interactivity&amp;lt;/u&amp;gt;: Style components and integrate interactive elements using CSS.&lt;br /&gt;
*&amp;lt;u&amp;gt;Testing&amp;lt;/u&amp;gt;: Perform individual component testing and end-to-end testing for the entire application.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
===Current Implementation (Ruby on Rails)===&lt;br /&gt;
&lt;br /&gt;
The existing interface on Expertiza, developed with Ruby on Rails, displays a student's task list with assignments, due dates, and progress indicators.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; Current Implementation of Expertiza with Ruby on Rails &amp;lt;/b&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Expertiza_current_implementation.jpg | 1000px]]&lt;br /&gt;
&lt;br /&gt;
===New Implementation (React JS &amp;amp; TypeScript)===&lt;br /&gt;
&lt;br /&gt;
Our updated UI replicates the functionality of the original page, now leveraging TypeScript's reliability alongside React's dynamic rendering. We prioritized building a responsive, accessible interface that aligns with modern design principles. We have also included certain features to make it easy for the student to manage their assignments.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt; Implementation Overview &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File: New_Implementation_Assignments_Page.jpg | 1000px ]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Fetch and Display Data:&amp;lt;/b&amp;gt; The UI is designed with future live data integration in mind. Currently, we use structured placeholder data to mimic backend interactions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Implementation Steps&amp;lt;/i&amp;gt;&lt;br /&gt;
*Defined TypeScript interfaces to model assignment data structures.&lt;br /&gt;
*Created mock data to simulate API responses for development.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. React Component Design:&amp;lt;/b&amp;gt; We developed modular React components like Header, TaskList, and TaskItem to improve code reusability and maintainability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; Legend &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have included a legend on the right of the student task list, to improve clarity, allowing users to understand column meanings at a glance. This approach is more user-friendly than requiring users to hover over a small info icon, and it provides a cleaner, more streamlined interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Implementation Steps&amp;lt;/i&amp;gt;&lt;br /&gt;
==== StudentTasksBox component ====&lt;br /&gt;
*Implementation of the StudentTasksBox component - [https://github.com/aditikilledar/reimplementation-front-end/blob/student-tasks-ui-f24/src/pages/StudentTasks/StudentTasksBox.tsx]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
const StudentTasksBox: React.FC&amp;lt;StudentTasksBoxProps&amp;gt; = ({ participantTasks, revisions, studentsTeamedWith }) =&amp;gt; {&lt;br /&gt;
    // Calculate total number of students teamed up with by iterating over each semester&lt;br /&gt;
    let totalStudents = 0;&lt;br /&gt;
    let allStudents: string[] = [];&lt;br /&gt;
    for (const semester in studentsTeamedWith) {&lt;br /&gt;
        // Add the number of students in each semester to the total count&lt;br /&gt;
        totalStudents += studentsTeamedWith[semester].length;&lt;br /&gt;
        allStudents = allStudents.concat(studentsTeamedWith[semester]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Calculate the number of revisions that are still pending (i.e., due date is in the future)&lt;br /&gt;
    const pendingRevisions = revisions.filter(revision =&amp;gt; getDaysLeft(revision.dueDate) &amp;gt; 0);&lt;br /&gt;
&lt;br /&gt;
    const dueTasks = participantTasks.filter(task =&amp;gt; getDaysLeft(task.stageDeadline) &amp;gt; 0);&lt;br /&gt;
&lt;br /&gt;
    // Group tasks by course&lt;br /&gt;
    const tasksByCourse: { [key: string]: typeof participantTasks } = {};&lt;br /&gt;
&lt;br /&gt;
    dueTasks.forEach(task =&amp;gt; {&lt;br /&gt;
        const courseName = task.course;&lt;br /&gt;
&lt;br /&gt;
        if (!tasksByCourse[courseName]) {&lt;br /&gt;
            tasksByCourse[courseName] = [];&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        tasksByCourse[courseName].push(task);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    return (&lt;br /&gt;
        &amp;lt;div className={styles.container}&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt;Task Summary&amp;lt;/h2&amp;gt;&lt;br /&gt;
            &amp;lt;div className={styles.infoBox}&amp;gt;&lt;br /&gt;
                &amp;lt;h5&amp;gt;Due:&amp;lt;/h5&amp;gt;&lt;br /&gt;
                {Object.entries(tasksByCourse).map(([course, tasks]) =&amp;gt; (&lt;br /&gt;
                    &amp;lt;div key={course}&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;{course}&amp;lt;/p&amp;gt;&lt;br /&gt;
                        &amp;lt;ul&amp;gt;&lt;br /&gt;
                            {tasks.map(task =&amp;gt; (&lt;br /&gt;
                                &amp;lt;li key={task.id}&amp;gt;&lt;br /&gt;
                                    {task.assignment} - Due: {task.stageDeadline}&lt;br /&gt;
                                &amp;lt;/li&amp;gt;&lt;br /&gt;
                            ))}&lt;br /&gt;
                        &amp;lt;/ul&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                ))}&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div className={styles.infoBox}&amp;gt;&lt;br /&gt;
                &amp;lt;h5&amp;gt;Revisions:&amp;lt;/h5&amp;gt;&lt;br /&gt;
                &amp;lt;ul&amp;gt;&lt;br /&gt;
                    {revisions.map((revision, index) =&amp;gt; (&lt;br /&gt;
                        &amp;lt;li key={index}&amp;gt;{revision.name}&amp;lt;/li&amp;gt;&lt;br /&gt;
                    ))}&lt;br /&gt;
                &amp;lt;/ul&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div className={styles.infoBox}&amp;gt;&lt;br /&gt;
                &amp;lt;div className={styles.teamedStudents}&amp;gt;&lt;br /&gt;
                    &amp;lt;h5&amp;gt;Total Students Teamed With: {totalStudents}&amp;lt;/h5&amp;gt;&lt;br /&gt;
                    &amp;lt;ul&amp;gt;&lt;br /&gt;
                        {allStudents.map((student, index) =&amp;gt; (&lt;br /&gt;
                            &amp;lt;li key={index}&amp;gt;{student}&amp;lt;/li&amp;gt;&lt;br /&gt;
                        ))}&lt;br /&gt;
                    &amp;lt;/ul&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;New UI for StudentTasksBox Component&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File: StudentTasksBox_Task Summary.jpg | 200px]]&lt;br /&gt;
[[File: StudentTasksBox_Revisions and Students Teamed With.jpg | 200px]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== StudentTaskHome component ====&lt;br /&gt;
*Implementation of the StudentTaskHome component that handles the list of assignments along with filters (dropdowns). [https://github.com/aditikilledar/reimplementation-front-end/blob/student-tasks-ui-f24/src/pages/StudentTasks/StudentTaskHome.tsx]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
const StudentTasksHome: React.FC = () =&amp;gt; {&lt;br /&gt;
    // init state and hooks&lt;br /&gt;
    const currUserId = testData.current_user_id;&lt;br /&gt;
    const dispatch = useDispatch();&lt;br /&gt;
    const navigate = useNavigate();&lt;br /&gt;
    const auth = useSelector((state: RootState) =&amp;gt; state.authentication)&lt;br /&gt;
&lt;br /&gt;
    type StudentsTeamedWith = {&lt;br /&gt;
        [semester: string]: string[];&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    // states to hold tasks&lt;br /&gt;
    const taskRevisions = testData.revisions;&lt;br /&gt;
    const participantTasks = testData.participantTasks;&lt;br /&gt;
    console.log(&amp;quot;participantTasks&amp;quot;, participantTasks)&lt;br /&gt;
&lt;br /&gt;
    const [tasks, setTasks] = useState&amp;lt;Task[]&amp;gt;([]);&lt;br /&gt;
    const dueTasks = testData.dueTasks;&lt;br /&gt;
    const studentsTeamedWith: StudentsTeamedWith = testData.studentsTeamedWith;&lt;br /&gt;
    const [filteredTasks, setFilteredTasks] = useState&amp;lt;Task[]&amp;gt;([]);&lt;br /&gt;
&lt;br /&gt;
    const [assignmentFilter, setAssignmentFilter] = useState('');&lt;br /&gt;
    const [courseFilter, setCourseFilter] = useState('');&lt;br /&gt;
    const [topicFilter, setTopicFilter] = useState('');&lt;br /&gt;
    const [currentstageFilter, setCurrentStageFilter] = useState('');&lt;br /&gt;
&lt;br /&gt;
    function togglePublishingRights(id: number): void {&lt;br /&gt;
        throw new Error('Function not implemented.');&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    let totalStudents = 0;&lt;br /&gt;
    let allStudents: string[] = [];&lt;br /&gt;
    for (const semester in studentsTeamedWith) {&lt;br /&gt;
        // Add the number of students in each semester to the total count&lt;br /&gt;
        totalStudents += studentsTeamedWith[semester].length;&lt;br /&gt;
        allStudents = allStudents.concat(studentsTeamedWith[semester]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    useEffect(() =&amp;gt; {&lt;br /&gt;
        // Map the data from participationTasks to the tasks state&lt;br /&gt;
        const mappedTasks = participantTasks.map(task =&amp;gt; ({&lt;br /&gt;
            id: task.id,&lt;br /&gt;
            assignment: task.assignment,&lt;br /&gt;
            course: task.course,&lt;br /&gt;
            topic: task.topic,&lt;br /&gt;
            currentStage: task.current_stage, // Adjust to match your data's structure&lt;br /&gt;
            reviewGrade: task.review_grade, // Can be a string or an object&lt;br /&gt;
            badges: task.badges, // Keep as is since it can be string or boolean&lt;br /&gt;
            stageDeadline: task.stage_deadline, // Adjust to match your data's structure&lt;br /&gt;
            publishingRights: task.publishing_rights, // Boolean type&lt;br /&gt;
        }));&lt;br /&gt;
&lt;br /&gt;
        setTasks(mappedTasks);&lt;br /&gt;
        setFilteredTasks(mappedTasks);&lt;br /&gt;
    }, [participantTasks]);&lt;br /&gt;
&lt;br /&gt;
    console.log(&amp;quot;after use effect:&amp;quot;, participantTasks)&lt;br /&gt;
&lt;br /&gt;
    useEffect(() =&amp;gt; {&lt;br /&gt;
        const filtered = tasks.filter((task) =&amp;gt;&lt;br /&gt;
            (assignmentFilter ? task.assignment === assignmentFilter : true) &amp;amp;&amp;amp;&lt;br /&gt;
            (courseFilter ? task.course === courseFilter : true) &amp;amp;&amp;amp;&lt;br /&gt;
            (topicFilter ? task.topic === topicFilter : true) &amp;amp;&amp;amp;&lt;br /&gt;
            (currentstageFilter ? task.topic == currentstageFilter : true)&lt;br /&gt;
        );&lt;br /&gt;
        setFilteredTasks(filtered);&lt;br /&gt;
    }, [assignmentFilter, courseFilter, topicFilter, currentstageFilter, tasks]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;New UI for StudentTaskHome Component&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
[[File: StudentTaskHome.jpg | 1000px ]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Table Filtering:&amp;lt;/b&amp;gt; The columns in the table are provided with filters enabling the user to search for what they want. The drop downs are provided for the columns: assignments, course, topic and current stage. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Implementation Steps&amp;lt;/i&amp;gt;&lt;br /&gt;
* Added the feature for filtering out tasks in the table by including the filteredtasks component in the StudentTasksHome.tsx file. &lt;br /&gt;
* The corresponding formatting for the same included in the StudentTasks.module.css file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;4. Error and Edge Case Handling:&amp;lt;/b&amp;gt; Comprehensive error handling and edge case handling strategies were implemented to provide informative feedback for failed requests or empty datasets.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;5. Responsive and Accessible Design:&amp;lt;/b&amp;gt; The page implemented is fully responsive on all devices (desktop, tablet, mobile) and meets accessibility standards, including ARIA roles, ensuring a seamless and inclusive experience for all students, regardless of their device or abilities.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;6. Testing and Validation:&amp;lt;/b&amp;gt; The testing phase of the project involves a manual testing process to ensure the student task view list functions reliably.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Implementation Steps&amp;lt;/i&amp;gt;&lt;br /&gt;
*Carrying out a detailed manual review of each task item to confirm they display accurate information, ensuring visual indicators match the design specifications.&lt;br /&gt;
*Simulating user interactions manually to verify that component links and buttons function correctly, confirming that all elements respond as expected.&lt;br /&gt;
*Evaluating visual feedback elements like hover and active states to ensure they align with the project's usability standards.&lt;br /&gt;
&lt;br /&gt;
These steps are intended to confirm the interface's cohesive functionality and reliability by interacting with the system from an end-user perspective. This hands-on approach enables quick correction of any inconsistencies and improvements to the user experience.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Login page for accessing the system&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File: Login_Page_Student_tasks_UI.jpg | 1000px ]]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Navigate to the &amp;quot;Assignments&amp;quot; tab to view list of assignments&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File: New_Implementation_Assignments_Page.jpg | 1000px ]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; Major changes made: &amp;lt;/b&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. We have included a legend to improve clarity, allowing users to understand column meanings at a glance. This approach is more user-friendly than requiring users to hover over a small info icon, and it provides a cleaner, more streamlined interface.&lt;br /&gt;
&lt;br /&gt;
2. We have split the task box into different parts making it easier for the user to view the Student Tasks Page.&lt;br /&gt;
&lt;br /&gt;
3. The Table containing the list of assignments have been provided with dropdowns for ease of access.&lt;br /&gt;
&lt;br /&gt;
==Database==&lt;br /&gt;
We prepared the database by cloning and configuring the reimplementation backend, adhering to the guidelines provided in the Backend Setup Instructions. We will be creating dummy assignment data for testing purposes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; Sample of the Dummy data created &amp;lt;/b&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
[[File: Dummy_data_Student_Tasks_UI.jpg | 500px]]&lt;br /&gt;
&lt;br /&gt;
==Components==&lt;br /&gt;
*&amp;lt;b&amp;gt;App.tsx :&amp;lt;/b&amp;gt; The `App.tsx` file acts as the primary entry point for a React application, setting up routing, integrating various pages and components, and managing global states or contexts to enable seamless navigation and functionality across the app. We’ll be adding a protected route for &amp;quot;StudentTaskHome&amp;quot; to direct users with the STUDENT role to the `StudentTasksHome` component.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;StudentTasksBox.tsx :&amp;lt;/b&amp;gt; The StudentTaskbox.tsx file will display a sidebar component that emphasizes upcoming tasks, revisions, and team collaborations.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;StudentTaskHome.tsx :&amp;lt;/b&amp;gt; The StudentTaskHome.tsx file contains the main panel, presenting a comprehensive list of assignments with course information, topics, current stages, and other relevant details. This contains the dropdowns implemented in the main panel (table) for filtering based on the user's needs.&lt;br /&gt;
&lt;br /&gt;
==Files created/modified==&lt;br /&gt;
* src/App.tsx (Modified) - This file was changed to point to the new implementation of the Student Tasks page.&lt;br /&gt;
&lt;br /&gt;
* src/pages/StudentTasks/StudentTasksHome.tsx (New File) - This file was created to handle the content of task table in the Student Tasks page.&lt;br /&gt;
  &lt;br /&gt;
* src/pages/StudentTasks/StudentTaskBox.tsx (New File) - This file was created to handle the content of the yellow task box in the Student Tasks page.&lt;br /&gt;
&lt;br /&gt;
* src/pages/StudentTasks/StudentTasks.module.css (New File) - This file was created to handle the styling of the tasks table.&lt;br /&gt;
 &lt;br /&gt;
* src/pages/StudentTasks/StudentTasksBox.module.css (New File) - This file was created to handle the styling of the yellow task box.&lt;br /&gt;
&lt;br /&gt;
* src/pages/StudentTasks/testData.json (New File) - This file was created to store the dummy data for our implementation.&lt;br /&gt;
&lt;br /&gt;
==Design Patterns and Principles==&lt;br /&gt;
&lt;br /&gt;
Design patterns and principles are fundamental concepts that help developers create clean, scalable, and maintainable code. They guide the design of software structures and improve development efficiency, as they provide solutions to common problems and offer a vocabulary for communication within development teams. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Open/Closed Principle (OCP):&amp;lt;/b&amp;gt; Software entities should be open for extension but closed for modification, allowing new functionality without altering existing code. It ensures modularity and reusability, which aligns with the goal of designing React components for different sections of the Student Task List page. The existing code was just altered by adding additional features.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Don't Repeat Yourself (DRY):&amp;lt;/b&amp;gt;Avoid duplicating code. When functionality or logic repeats, it's better to refactor it into reusable functions, classes, or modules. The StudentTaskHome and StudentTasksBox components have all the required code and have been refactored to make it reusable.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Component Design and Structure:&amp;lt;/b&amp;gt; Design and organize React components to effectively support the Student Task List page, ensuring clarity and modularity.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Test Cases:&amp;lt;/i&amp;gt;&lt;br /&gt;
* Review the modular design of key components (e.g., header, task list, individual task items) for scalability and reusability.&lt;br /&gt;
* Check each component for proper structure and verify that all necessary information is displayed as expected.&lt;br /&gt;
* Confirm each component renders correctly within the overall page layout.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Task List Display:&amp;lt;/b&amp;gt; Implement functionality to accurately fetch and display assignments within the task list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Test Cases:&amp;lt;/i&amp;gt;&lt;br /&gt;
* Confirm that the task list properly renders each fetched assignment.&lt;br /&gt;
* Test for infinite scrolling, if needed, to handle extensive assignment lists smoothly.&lt;br /&gt;
* Verify that loading indicators or placeholders appear while data is loading, ensuring user feedback during fetch operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Filter Assignments:&amp;lt;/b&amp;gt; Ensure that the task list filters assignments to show only those relevant to the current user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Test Cases:&amp;lt;/i&amp;gt;&lt;br /&gt;
* Confirm the task list is correctly filtered based on the User ID, displaying only applicable assignments for the user.&lt;br /&gt;
&lt;br /&gt;
== Important Links ==&lt;br /&gt;
* GitHub repo [https://github.com/aditikilledar/reimplementation-front-end]&lt;br /&gt;
* Pull Request: [https://github.com/expertiza/reimplementation-front-end/pull/66]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=====Mentor===== &lt;br /&gt;
&lt;br /&gt;
* Chaitanya Srusti &amp;lt;crsrusti@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Members===== &lt;br /&gt;
* Aditi Killedar &amp;lt;akilled@ncsu.edu&amp;gt;&lt;br /&gt;
* Kruthi Rajeshwar &amp;lt;krajesh@ncsu.edu&amp;gt;&lt;br /&gt;
* Sphurthy Satish &amp;lt;sphurthy@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2463_Implement_Front_End_for_Student_Task_List&amp;diff=157997</id>
		<title>CSC/ECE 517 Fall 2024 - E2463 Implement Front End for Student Task List</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2463_Implement_Front_End_for_Student_Task_List&amp;diff=157997"/>
		<updated>2024-10-30T01:05:48Z</updated>

		<summary type="html">&lt;p&gt;Akilled: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Expertiza ==&lt;br /&gt;
Expertiza is an open-source learning management system primarily developed with Ruby on Rails. It offers features such as creating tests and assignments, managing teams and courses, and, most importantly, providing a robust framework for peer reviews and group feedback. This project focuses on developing frontend components in React, with an emphasis on the Student Task list page. The aim is to build a fully operational user interface for these components using React.js and TypeScript.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
The main objective of this project is to implement the front end for the Student Task list page within Expertiza.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
===Objective===&lt;br /&gt;
This project’s goal is to redesign the front end of the current non-TypeScript Student Task List page on Expertiza by building a new user interface with React.js and TypeScript, ensuring a more type-safe development experience. The page will showcase all assignments the user is involved in, requiring data fetching to obtain the assignment list, filtering based on the user’s participation, and presenting the results in a visually engaging, user-friendly format through React components.&lt;br /&gt;
This is the visual framework for creating the user interface:&lt;br /&gt;
&lt;br /&gt;
[[File: Flow_Chart_Student_tasks.jpg | 1000px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Development Steps===&lt;br /&gt;
*&amp;lt;u&amp;gt;Review Current Interface&amp;lt;/u&amp;gt;:  Conduct a detailed analysis of the existing Ruby on Rails UI to understand its layout and features.&lt;br /&gt;
*&amp;lt;u&amp;gt;Setup Development Environment&amp;lt;/u&amp;gt;: Configure the environment to work with TypeScript and React.&lt;br /&gt;
*&amp;lt;u&amp;gt;Design Components&amp;lt;/u&amp;gt;: Break down the UI into distinct React components, defining the props and states needed for each.&lt;br /&gt;
*&amp;lt;u&amp;gt;Implement in Typescript&amp;lt;/u&amp;gt;: Develop the component logic in TypeScript, prioritizing type safety.&lt;br /&gt;
*&amp;lt;u&amp;gt;Replicate Functionality&amp;lt;/u&amp;gt;: Ensure all features from the Rails application are mirrored in the React components, maintaining full functionality.&lt;br /&gt;
*&amp;lt;u&amp;gt;Styling and Add Interactivity&amp;lt;/u&amp;gt;: Style components and integrate interactive elements using CSS.&lt;br /&gt;
*&amp;lt;u&amp;gt;Testing&amp;lt;/u&amp;gt;: Perform individual component testing and end-to-end testing for the entire application.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
===Current Implementation (Ruby on Rails)===&lt;br /&gt;
&lt;br /&gt;
The existing interface on Expertiza, developed with Ruby on Rails, displays a student's task list with assignments, due dates, and progress indicators.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; Current Implementation of Expertiza with Ruby on Rails &amp;lt;/b&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Expertiza_current_implementation.jpg | 1000px]]&lt;br /&gt;
&lt;br /&gt;
===New Implementation (React JS &amp;amp; TypeScript)===&lt;br /&gt;
&lt;br /&gt;
Our updated UI replicates the functionality of the original page, now leveraging TypeScript's reliability alongside React's dynamic rendering. We prioritized building a responsive, accessible interface that aligns with modern design principles. We have also included certain features to make it easy for the student to manage their assignments.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt; Implementation Overview &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Fetch and Display Data:&amp;lt;/b&amp;gt; The UI is designed with future live data integration in mind. Currently, we use structured placeholder data to mimic backend interactions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Implementation Steps&amp;lt;/i&amp;gt;&lt;br /&gt;
*Defined TypeScript interfaces to model assignment data structures.&lt;br /&gt;
*Created mock data to simulate API responses for development.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. React Component Design:&amp;lt;/b&amp;gt; We developed modular React components like Header, TaskList, and TaskItem to improve code reusability and maintainability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; Legend &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have included a legend on the right of the student task list, to improve clarity, allowing users to understand column meanings at a glance. This approach is more user-friendly than requiring users to hover over a small info icon, and it provides a cleaner, more streamlined interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Implementation Steps&amp;lt;/i&amp;gt;&lt;br /&gt;
==== StudentTasksBox component ====&lt;br /&gt;
*Implementation of the StudentTasksBox component - [https://github.com/aditikilledar/reimplementation-front-end/blob/student-tasks-ui-f24/src/pages/StudentTasks/StudentTasksBox.tsx]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
const StudentTasksBox: React.FC&amp;lt;StudentTasksBoxProps&amp;gt; = ({ participantTasks, revisions, studentsTeamedWith }) =&amp;gt; {&lt;br /&gt;
    // Calculate total number of students teamed up with by iterating over each semester&lt;br /&gt;
    let totalStudents = 0;&lt;br /&gt;
    let allStudents: string[] = [];&lt;br /&gt;
    for (const semester in studentsTeamedWith) {&lt;br /&gt;
        // Add the number of students in each semester to the total count&lt;br /&gt;
        totalStudents += studentsTeamedWith[semester].length;&lt;br /&gt;
        allStudents = allStudents.concat(studentsTeamedWith[semester]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Calculate the number of revisions that are still pending (i.e., due date is in the future)&lt;br /&gt;
    const pendingRevisions = revisions.filter(revision =&amp;gt; getDaysLeft(revision.dueDate) &amp;gt; 0);&lt;br /&gt;
&lt;br /&gt;
    const dueTasks = participantTasks.filter(task =&amp;gt; getDaysLeft(task.stageDeadline) &amp;gt; 0);&lt;br /&gt;
&lt;br /&gt;
    // Group tasks by course&lt;br /&gt;
    const tasksByCourse: { [key: string]: typeof participantTasks } = {};&lt;br /&gt;
&lt;br /&gt;
    dueTasks.forEach(task =&amp;gt; {&lt;br /&gt;
        const courseName = task.course;&lt;br /&gt;
&lt;br /&gt;
        if (!tasksByCourse[courseName]) {&lt;br /&gt;
            tasksByCourse[courseName] = [];&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        tasksByCourse[courseName].push(task);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    return (&lt;br /&gt;
        &amp;lt;div className={styles.container}&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt;Task Summary&amp;lt;/h2&amp;gt;&lt;br /&gt;
            &amp;lt;div className={styles.infoBox}&amp;gt;&lt;br /&gt;
                &amp;lt;h5&amp;gt;Due:&amp;lt;/h5&amp;gt;&lt;br /&gt;
                {Object.entries(tasksByCourse).map(([course, tasks]) =&amp;gt; (&lt;br /&gt;
                    &amp;lt;div key={course}&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;{course}&amp;lt;/p&amp;gt;&lt;br /&gt;
                        &amp;lt;ul&amp;gt;&lt;br /&gt;
                            {tasks.map(task =&amp;gt; (&lt;br /&gt;
                                &amp;lt;li key={task.id}&amp;gt;&lt;br /&gt;
                                    {task.assignment} - Due: {task.stageDeadline}&lt;br /&gt;
                                &amp;lt;/li&amp;gt;&lt;br /&gt;
                            ))}&lt;br /&gt;
                        &amp;lt;/ul&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                ))}&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div className={styles.infoBox}&amp;gt;&lt;br /&gt;
                &amp;lt;h5&amp;gt;Revisions:&amp;lt;/h5&amp;gt;&lt;br /&gt;
                &amp;lt;ul&amp;gt;&lt;br /&gt;
                    {revisions.map((revision, index) =&amp;gt; (&lt;br /&gt;
                        &amp;lt;li key={index}&amp;gt;{revision.name}&amp;lt;/li&amp;gt;&lt;br /&gt;
                    ))}&lt;br /&gt;
                &amp;lt;/ul&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div className={styles.infoBox}&amp;gt;&lt;br /&gt;
                &amp;lt;div className={styles.teamedStudents}&amp;gt;&lt;br /&gt;
                    &amp;lt;h5&amp;gt;Total Students Teamed With: {totalStudents}&amp;lt;/h5&amp;gt;&lt;br /&gt;
                    &amp;lt;ul&amp;gt;&lt;br /&gt;
                        {allStudents.map((student, index) =&amp;gt; (&lt;br /&gt;
                            &amp;lt;li key={index}&amp;gt;{student}&amp;lt;/li&amp;gt;&lt;br /&gt;
                        ))}&lt;br /&gt;
                    &amp;lt;/ul&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;New UI for StudentTasksBox Component&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File: StudentTasksBox_Task Summary.jpg | 200px]]&lt;br /&gt;
[[File: StudentTasksBox_Revisions and Students Teamed With.jpg | 200px]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== StudentTaskHome component ====&lt;br /&gt;
*Implementation of the StudentTaskHome component that handles the list of assignments along with filters (dropdowns). [https://github.com/aditikilledar/reimplementation-front-end/blob/student-tasks-ui-f24/src/pages/StudentTasks/StudentTaskHome.tsx]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
const StudentTasksHome: React.FC = () =&amp;gt; {&lt;br /&gt;
    // init state and hooks&lt;br /&gt;
    const currUserId = testData.current_user_id;&lt;br /&gt;
    const dispatch = useDispatch();&lt;br /&gt;
    const navigate = useNavigate();&lt;br /&gt;
    const auth = useSelector((state: RootState) =&amp;gt; state.authentication)&lt;br /&gt;
&lt;br /&gt;
    type StudentsTeamedWith = {&lt;br /&gt;
        [semester: string]: string[];&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    // states to hold tasks&lt;br /&gt;
    const taskRevisions = testData.revisions;&lt;br /&gt;
    const participantTasks = testData.participantTasks;&lt;br /&gt;
    console.log(&amp;quot;participantTasks&amp;quot;, participantTasks)&lt;br /&gt;
&lt;br /&gt;
    const [tasks, setTasks] = useState&amp;lt;Task[]&amp;gt;([]);&lt;br /&gt;
    const dueTasks = testData.dueTasks;&lt;br /&gt;
    const studentsTeamedWith: StudentsTeamedWith = testData.studentsTeamedWith;&lt;br /&gt;
    const [filteredTasks, setFilteredTasks] = useState&amp;lt;Task[]&amp;gt;([]);&lt;br /&gt;
&lt;br /&gt;
    const [assignmentFilter, setAssignmentFilter] = useState('');&lt;br /&gt;
    const [courseFilter, setCourseFilter] = useState('');&lt;br /&gt;
    const [topicFilter, setTopicFilter] = useState('');&lt;br /&gt;
    const [currentstageFilter, setCurrentStageFilter] = useState('');&lt;br /&gt;
&lt;br /&gt;
    function togglePublishingRights(id: number): void {&lt;br /&gt;
        throw new Error('Function not implemented.');&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    let totalStudents = 0;&lt;br /&gt;
    let allStudents: string[] = [];&lt;br /&gt;
    for (const semester in studentsTeamedWith) {&lt;br /&gt;
        // Add the number of students in each semester to the total count&lt;br /&gt;
        totalStudents += studentsTeamedWith[semester].length;&lt;br /&gt;
        allStudents = allStudents.concat(studentsTeamedWith[semester]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    useEffect(() =&amp;gt; {&lt;br /&gt;
        // Map the data from participationTasks to the tasks state&lt;br /&gt;
        const mappedTasks = participantTasks.map(task =&amp;gt; ({&lt;br /&gt;
            id: task.id,&lt;br /&gt;
            assignment: task.assignment,&lt;br /&gt;
            course: task.course,&lt;br /&gt;
            topic: task.topic,&lt;br /&gt;
            currentStage: task.current_stage, // Adjust to match your data's structure&lt;br /&gt;
            reviewGrade: task.review_grade, // Can be a string or an object&lt;br /&gt;
            badges: task.badges, // Keep as is since it can be string or boolean&lt;br /&gt;
            stageDeadline: task.stage_deadline, // Adjust to match your data's structure&lt;br /&gt;
            publishingRights: task.publishing_rights, // Boolean type&lt;br /&gt;
        }));&lt;br /&gt;
&lt;br /&gt;
        setTasks(mappedTasks);&lt;br /&gt;
        setFilteredTasks(mappedTasks);&lt;br /&gt;
    }, [participantTasks]);&lt;br /&gt;
&lt;br /&gt;
    console.log(&amp;quot;after use effect:&amp;quot;, participantTasks)&lt;br /&gt;
&lt;br /&gt;
    useEffect(() =&amp;gt; {&lt;br /&gt;
        const filtered = tasks.filter((task) =&amp;gt;&lt;br /&gt;
            (assignmentFilter ? task.assignment === assignmentFilter : true) &amp;amp;&amp;amp;&lt;br /&gt;
            (courseFilter ? task.course === courseFilter : true) &amp;amp;&amp;amp;&lt;br /&gt;
            (topicFilter ? task.topic === topicFilter : true) &amp;amp;&amp;amp;&lt;br /&gt;
            (currentstageFilter ? task.topic == currentstageFilter : true)&lt;br /&gt;
        );&lt;br /&gt;
        setFilteredTasks(filtered);&lt;br /&gt;
    }, [assignmentFilter, courseFilter, topicFilter, currentstageFilter, tasks]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;New UI for StudentTaskHome Component&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
[[File: StudentTaskHome.jpg | 1000px ]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Table Filtering:&amp;lt;/b&amp;gt; The columns in the table are provided with filters enabling the user to search for what they want. The drop downs are provided for the columns: assignments, course, topic and current stage. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Implementation Steps&amp;lt;/i&amp;gt;&lt;br /&gt;
* Added the feature for filtering out tasks in the table by including the filteredtasks component in the StudentTasksHome.tsx file. &lt;br /&gt;
* The corresponding formatting for the same included in the StudentTasks.module.css file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;4. Error and Edge Case Handling:&amp;lt;/b&amp;gt; Comprehensive error handling and edge case handling strategies were implemented to provide informative feedback for failed requests or empty datasets.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;5. Responsive and Accessible Design:&amp;lt;/b&amp;gt; The page implemented is fully responsive on all devices (desktop, tablet, mobile) and meets accessibility standards, including ARIA roles, ensuring a seamless and inclusive experience for all students, regardless of their device or abilities.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;6. Testing and Validation:&amp;lt;/b&amp;gt; The testing phase of the project involves a manual testing process to ensure the student task view list functions reliably.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Implementation Steps&amp;lt;/i&amp;gt;&lt;br /&gt;
*Carrying out a detailed manual review of each task item to confirm they display accurate information, ensuring visual indicators match the design specifications.&lt;br /&gt;
*Simulating user interactions manually to verify that component links and buttons function correctly, confirming that all elements respond as expected.&lt;br /&gt;
*Evaluating visual feedback elements like hover and active states to ensure they align with the project's usability standards.&lt;br /&gt;
&lt;br /&gt;
These steps are intended to confirm the interface's cohesive functionality and reliability by interacting with the system from an end-user perspective. This hands-on approach enables quick correction of any inconsistencies and improvements to the user experience.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Login page for accessing the system&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File: Login_Page_Student_tasks_UI.jpg | 1000px ]]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Navigate to the &amp;quot;Assignments&amp;quot; tab to view list of assignments&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File: New_Implementation_Assignments_Page.jpg | 1000px ]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Database==&lt;br /&gt;
We prepared the database by cloning and configuring the reimplementation backend, adhering to the guidelines provided in the Backend Setup Instructions. We will be creating dummy assignment data for testing purposes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; Sample of the Dummy data created &amp;lt;/b&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
[[File: Dummy_data_Student_Tasks_UI.jpg | 500px]]&lt;br /&gt;
&lt;br /&gt;
==Components==&lt;br /&gt;
*&amp;lt;b&amp;gt;App.tsx :&amp;lt;/b&amp;gt; The `App.tsx` file acts as the primary entry point for a React application, setting up routing, integrating various pages and components, and managing global states or contexts to enable seamless navigation and functionality across the app. We’ll be adding a protected route for &amp;quot;StudentTaskHome&amp;quot; to direct users with the STUDENT role to the `StudentTasksHome` component.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;StudentTasksBox.tsx :&amp;lt;/b&amp;gt; The StudentTaskbox.tsx file will display a sidebar component that emphasizes upcoming tasks, revisions, and team collaborations.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;StudentTaskHome.tsx :&amp;lt;/b&amp;gt; The StudentTaskHome.tsx file contains the main panel, presenting a comprehensive list of assignments with course information, topics, current stages, and other relevant details. This contains the dropdowns implemented in the main panel (table) for filtering based on the user's needs.&lt;br /&gt;
&lt;br /&gt;
==Files created/modified==&lt;br /&gt;
* src/App.tsx (Modified) - This file was changed to point to the new implementation of the Student Tasks page.&lt;br /&gt;
&lt;br /&gt;
* src/pages/StudentTasks/StudentTasksHome.tsx (New File) - This file was created to handle the content of task table in the Student Tasks page.&lt;br /&gt;
  &lt;br /&gt;
* src/pages/StudentTasks/StudentTaskBox.tsx (New File) - This file was created to handle the content of the yellow task box in the Student Tasks page.&lt;br /&gt;
&lt;br /&gt;
* src/pages/StudentTasks/StudentTasks.module.css (New File) - This file was created to handle the styling of the tasks table.&lt;br /&gt;
 &lt;br /&gt;
* src/pages/StudentTasks/StudentTasksBox.module.css (New File) - This file was created to handle the styling of the yellow task box.&lt;br /&gt;
&lt;br /&gt;
* src/pages/StudentTasks/testData.json (New File) - This file was created to store the dummy data for our implementation.&lt;br /&gt;
&lt;br /&gt;
==Design Patterns and Principles==&lt;br /&gt;
&lt;br /&gt;
Design patterns and principles are fundamental concepts that help developers create clean, scalable, and maintainable code. They guide the design of software structures and improve development efficiency, as they provide solutions to common problems and offer a vocabulary for communication within development teams. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Open/Closed Principle (OCP):&amp;lt;/b&amp;gt; Software entities should be open for extension but closed for modification, allowing new functionality without altering existing code. It ensures modularity and reusability, which aligns with the goal of designing React components for different sections of the Student Task List page. The existing code was just altered by adding additional features.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Don't Repeat Yourself (DRY):&amp;lt;/b&amp;gt;Avoid duplicating code. When functionality or logic repeats, it's better to refactor it into reusable functions, classes, or modules. The StudentTaskHome and StudentTasksBox components have all the required code and have been refactored to make it reusable.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Component Design and Structure:&amp;lt;/b&amp;gt; Design and organize React components to effectively support the Student Task List page, ensuring clarity and modularity.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Test Cases:&amp;lt;/i&amp;gt;&lt;br /&gt;
* Review the modular design of key components (e.g., header, task list, individual task items) for scalability and reusability.&lt;br /&gt;
* Check each component for proper structure and verify that all necessary information is displayed as expected.&lt;br /&gt;
* Confirm each component renders correctly within the overall page layout.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Task List Display:&amp;lt;/b&amp;gt; Implement functionality to accurately fetch and display assignments within the task list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Test Cases:&amp;lt;/i&amp;gt;&lt;br /&gt;
* Confirm that the task list properly renders each fetched assignment.&lt;br /&gt;
* Test for infinite scrolling, if needed, to handle extensive assignment lists smoothly.&lt;br /&gt;
* Verify that loading indicators or placeholders appear while data is loading, ensuring user feedback during fetch operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Filter Assignments:&amp;lt;/b&amp;gt; Ensure that the task list filters assignments to show only those relevant to the current user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Test Cases:&amp;lt;/i&amp;gt;&lt;br /&gt;
* Confirm the task list is correctly filtered based on the User ID, displaying only applicable assignments for the user.&lt;br /&gt;
&lt;br /&gt;
== Important Links ==&lt;br /&gt;
* GitHub repo [https://github.com/aditikilledar/reimplementation-front-end]&lt;br /&gt;
* Pull Request: [https://github.com/expertiza/reimplementation-front-end/pull/66]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=====Mentor===== &lt;br /&gt;
&lt;br /&gt;
* Chaitanya Srusti &amp;lt;crsrusti@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Members===== &lt;br /&gt;
* Aditi Killedar &amp;lt;akilled@ncsu.edu&amp;gt;&lt;br /&gt;
* Kruthi Rajeshwar &amp;lt;krajesh@ncsu.edu&amp;gt;&lt;br /&gt;
* Sphurthy Satish &amp;lt;sphurthy@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2463_Implement_Front_End_for_Student_Task_List&amp;diff=157996</id>
		<title>CSC/ECE 517 Fall 2024 - E2463 Implement Front End for Student Task List</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2463_Implement_Front_End_for_Student_Task_List&amp;diff=157996"/>
		<updated>2024-10-30T01:04:43Z</updated>

		<summary type="html">&lt;p&gt;Akilled: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Expertiza ==&lt;br /&gt;
Expertiza is an open-source learning management system primarily developed with Ruby on Rails. It offers features such as creating tests and assignments, managing teams and courses, and, most importantly, providing a robust framework for peer reviews and group feedback. This project focuses on developing frontend components in React, with an emphasis on the Student Task list page. The aim is to build a fully operational user interface for these components using React.js and TypeScript.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
The main objective of this project is to implement the front end for the Student Task list page within Expertiza.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
===Objective===&lt;br /&gt;
This project’s goal is to redesign the front end of the current non-TypeScript Student Task List page on Expertiza by building a new user interface with React.js and TypeScript, ensuring a more type-safe development experience. The page will showcase all assignments the user is involved in, requiring data fetching to obtain the assignment list, filtering based on the user’s participation, and presenting the results in a visually engaging, user-friendly format through React components.&lt;br /&gt;
This is the visual framework for creating the user interface:&lt;br /&gt;
&lt;br /&gt;
[[File: Flow_Chart_Student_tasks.jpg | 1000px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Development Steps===&lt;br /&gt;
*&amp;lt;u&amp;gt;Review Current Interface&amp;lt;/u&amp;gt;:  Conduct a detailed analysis of the existing Ruby on Rails UI to understand its layout and features.&lt;br /&gt;
*&amp;lt;u&amp;gt;Setup Development Environment&amp;lt;/u&amp;gt;: Configure the environment to work with TypeScript and React.&lt;br /&gt;
*&amp;lt;u&amp;gt;Design Components&amp;lt;/u&amp;gt;: Break down the UI into distinct React components, defining the props and states needed for each.&lt;br /&gt;
*&amp;lt;u&amp;gt;Implement in Typescript&amp;lt;/u&amp;gt;: Develop the component logic in TypeScript, prioritizing type safety.&lt;br /&gt;
*&amp;lt;u&amp;gt;Replicate Functionality&amp;lt;/u&amp;gt;: Ensure all features from the Rails application are mirrored in the React components, maintaining full functionality.&lt;br /&gt;
*&amp;lt;u&amp;gt;Styling and Add Interactivity&amp;lt;/u&amp;gt;: Style components and integrate interactive elements using CSS.&lt;br /&gt;
*&amp;lt;u&amp;gt;Testing&amp;lt;/u&amp;gt;: Perform individual component testing and end-to-end testing for the entire application.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
===Current Implementation (Ruby on Rails)===&lt;br /&gt;
&lt;br /&gt;
The existing interface on Expertiza, developed with Ruby on Rails, displays a student's task list with assignments, due dates, and progress indicators.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; Current Implementation of Expertiza with Ruby on Rails &amp;lt;/b&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Expertiza_current_implementation.jpg | 1000px]]&lt;br /&gt;
&lt;br /&gt;
===New Implementation (React JS &amp;amp; TypeScript)===&lt;br /&gt;
&lt;br /&gt;
Our updated UI replicates the functionality of the original page, now leveraging TypeScript's reliability alongside React's dynamic rendering. We prioritized building a responsive, accessible interface that aligns with modern design principles. We have also included certain features to make it easy for the student to manage their assignments.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt; Implementation Overview &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Fetch and Display Data:&amp;lt;/b&amp;gt; The UI is designed with future live data integration in mind. Currently, we use structured placeholder data to mimic backend interactions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Implementation Steps&amp;lt;/i&amp;gt;&lt;br /&gt;
*Defined TypeScript interfaces to model assignment data structures.&lt;br /&gt;
*Created mock data to simulate API responses for development.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. React Component Design:&amp;lt;/b&amp;gt; We developed modular React components like Header, TaskList, and TaskItem to improve code reusability and maintainability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Implementation Steps&amp;lt;/i&amp;gt;&lt;br /&gt;
==== StudentTasksBox component ====&lt;br /&gt;
*Implementation of the StudentTasksBox component - [https://github.com/aditikilledar/reimplementation-front-end/blob/student-tasks-ui-f24/src/pages/StudentTasks/StudentTasksBox.tsx]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
const StudentTasksBox: React.FC&amp;lt;StudentTasksBoxProps&amp;gt; = ({ participantTasks, revisions, studentsTeamedWith }) =&amp;gt; {&lt;br /&gt;
    // Calculate total number of students teamed up with by iterating over each semester&lt;br /&gt;
    let totalStudents = 0;&lt;br /&gt;
    let allStudents: string[] = [];&lt;br /&gt;
    for (const semester in studentsTeamedWith) {&lt;br /&gt;
        // Add the number of students in each semester to the total count&lt;br /&gt;
        totalStudents += studentsTeamedWith[semester].length;&lt;br /&gt;
        allStudents = allStudents.concat(studentsTeamedWith[semester]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Calculate the number of revisions that are still pending (i.e., due date is in the future)&lt;br /&gt;
    const pendingRevisions = revisions.filter(revision =&amp;gt; getDaysLeft(revision.dueDate) &amp;gt; 0);&lt;br /&gt;
&lt;br /&gt;
    const dueTasks = participantTasks.filter(task =&amp;gt; getDaysLeft(task.stageDeadline) &amp;gt; 0);&lt;br /&gt;
&lt;br /&gt;
    // Group tasks by course&lt;br /&gt;
    const tasksByCourse: { [key: string]: typeof participantTasks } = {};&lt;br /&gt;
&lt;br /&gt;
    dueTasks.forEach(task =&amp;gt; {&lt;br /&gt;
        const courseName = task.course;&lt;br /&gt;
&lt;br /&gt;
        if (!tasksByCourse[courseName]) {&lt;br /&gt;
            tasksByCourse[courseName] = [];&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        tasksByCourse[courseName].push(task);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    return (&lt;br /&gt;
        &amp;lt;div className={styles.container}&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt;Task Summary&amp;lt;/h2&amp;gt;&lt;br /&gt;
            &amp;lt;div className={styles.infoBox}&amp;gt;&lt;br /&gt;
                &amp;lt;h5&amp;gt;Due:&amp;lt;/h5&amp;gt;&lt;br /&gt;
                {Object.entries(tasksByCourse).map(([course, tasks]) =&amp;gt; (&lt;br /&gt;
                    &amp;lt;div key={course}&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;{course}&amp;lt;/p&amp;gt;&lt;br /&gt;
                        &amp;lt;ul&amp;gt;&lt;br /&gt;
                            {tasks.map(task =&amp;gt; (&lt;br /&gt;
                                &amp;lt;li key={task.id}&amp;gt;&lt;br /&gt;
                                    {task.assignment} - Due: {task.stageDeadline}&lt;br /&gt;
                                &amp;lt;/li&amp;gt;&lt;br /&gt;
                            ))}&lt;br /&gt;
                        &amp;lt;/ul&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                ))}&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div className={styles.infoBox}&amp;gt;&lt;br /&gt;
                &amp;lt;h5&amp;gt;Revisions:&amp;lt;/h5&amp;gt;&lt;br /&gt;
                &amp;lt;ul&amp;gt;&lt;br /&gt;
                    {revisions.map((revision, index) =&amp;gt; (&lt;br /&gt;
                        &amp;lt;li key={index}&amp;gt;{revision.name}&amp;lt;/li&amp;gt;&lt;br /&gt;
                    ))}&lt;br /&gt;
                &amp;lt;/ul&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div className={styles.infoBox}&amp;gt;&lt;br /&gt;
                &amp;lt;div className={styles.teamedStudents}&amp;gt;&lt;br /&gt;
                    &amp;lt;h5&amp;gt;Total Students Teamed With: {totalStudents}&amp;lt;/h5&amp;gt;&lt;br /&gt;
                    &amp;lt;ul&amp;gt;&lt;br /&gt;
                        {allStudents.map((student, index) =&amp;gt; (&lt;br /&gt;
                            &amp;lt;li key={index}&amp;gt;{student}&amp;lt;/li&amp;gt;&lt;br /&gt;
                        ))}&lt;br /&gt;
                    &amp;lt;/ul&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;New UI for StudentTasksBox Component&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File: StudentTasksBox_Task Summary.jpg | 200px]]&lt;br /&gt;
[[File: StudentTasksBox_Revisions and Students Teamed With.jpg | 200px]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== StudentTaskHome component ====&lt;br /&gt;
*Implementation of the StudentTaskHome component that handles the list of assignments along with filters (dropdowns). [https://github.com/aditikilledar/reimplementation-front-end/blob/student-tasks-ui-f24/src/pages/StudentTasks/StudentTaskHome.tsx]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
const StudentTasksHome: React.FC = () =&amp;gt; {&lt;br /&gt;
    // init state and hooks&lt;br /&gt;
    const currUserId = testData.current_user_id;&lt;br /&gt;
    const dispatch = useDispatch();&lt;br /&gt;
    const navigate = useNavigate();&lt;br /&gt;
    const auth = useSelector((state: RootState) =&amp;gt; state.authentication)&lt;br /&gt;
&lt;br /&gt;
    type StudentsTeamedWith = {&lt;br /&gt;
        [semester: string]: string[];&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    // states to hold tasks&lt;br /&gt;
    const taskRevisions = testData.revisions;&lt;br /&gt;
    const participantTasks = testData.participantTasks;&lt;br /&gt;
    console.log(&amp;quot;participantTasks&amp;quot;, participantTasks)&lt;br /&gt;
&lt;br /&gt;
    const [tasks, setTasks] = useState&amp;lt;Task[]&amp;gt;([]);&lt;br /&gt;
    const dueTasks = testData.dueTasks;&lt;br /&gt;
    const studentsTeamedWith: StudentsTeamedWith = testData.studentsTeamedWith;&lt;br /&gt;
    const [filteredTasks, setFilteredTasks] = useState&amp;lt;Task[]&amp;gt;([]);&lt;br /&gt;
&lt;br /&gt;
    const [assignmentFilter, setAssignmentFilter] = useState('');&lt;br /&gt;
    const [courseFilter, setCourseFilter] = useState('');&lt;br /&gt;
    const [topicFilter, setTopicFilter] = useState('');&lt;br /&gt;
    const [currentstageFilter, setCurrentStageFilter] = useState('');&lt;br /&gt;
&lt;br /&gt;
    function togglePublishingRights(id: number): void {&lt;br /&gt;
        throw new Error('Function not implemented.');&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    let totalStudents = 0;&lt;br /&gt;
    let allStudents: string[] = [];&lt;br /&gt;
    for (const semester in studentsTeamedWith) {&lt;br /&gt;
        // Add the number of students in each semester to the total count&lt;br /&gt;
        totalStudents += studentsTeamedWith[semester].length;&lt;br /&gt;
        allStudents = allStudents.concat(studentsTeamedWith[semester]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    useEffect(() =&amp;gt; {&lt;br /&gt;
        // Map the data from participationTasks to the tasks state&lt;br /&gt;
        const mappedTasks = participantTasks.map(task =&amp;gt; ({&lt;br /&gt;
            id: task.id,&lt;br /&gt;
            assignment: task.assignment,&lt;br /&gt;
            course: task.course,&lt;br /&gt;
            topic: task.topic,&lt;br /&gt;
            currentStage: task.current_stage, // Adjust to match your data's structure&lt;br /&gt;
            reviewGrade: task.review_grade, // Can be a string or an object&lt;br /&gt;
            badges: task.badges, // Keep as is since it can be string or boolean&lt;br /&gt;
            stageDeadline: task.stage_deadline, // Adjust to match your data's structure&lt;br /&gt;
            publishingRights: task.publishing_rights, // Boolean type&lt;br /&gt;
        }));&lt;br /&gt;
&lt;br /&gt;
        setTasks(mappedTasks);&lt;br /&gt;
        setFilteredTasks(mappedTasks);&lt;br /&gt;
    }, [participantTasks]);&lt;br /&gt;
&lt;br /&gt;
    console.log(&amp;quot;after use effect:&amp;quot;, participantTasks)&lt;br /&gt;
&lt;br /&gt;
    useEffect(() =&amp;gt; {&lt;br /&gt;
        const filtered = tasks.filter((task) =&amp;gt;&lt;br /&gt;
            (assignmentFilter ? task.assignment === assignmentFilter : true) &amp;amp;&amp;amp;&lt;br /&gt;
            (courseFilter ? task.course === courseFilter : true) &amp;amp;&amp;amp;&lt;br /&gt;
            (topicFilter ? task.topic === topicFilter : true) &amp;amp;&amp;amp;&lt;br /&gt;
            (currentstageFilter ? task.topic == currentstageFilter : true)&lt;br /&gt;
        );&lt;br /&gt;
        setFilteredTasks(filtered);&lt;br /&gt;
    }, [assignmentFilter, courseFilter, topicFilter, currentstageFilter, tasks]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;New UI for StudentTaskHome Component&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
[[File: StudentTaskHome.jpg | 1000px ]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Table Filtering:&amp;lt;/b&amp;gt; The columns in the table are provided with filters enabling the user to search for what they want. The drop downs are provided for the columns: assignments, course, topic and current stage. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Implementation Steps&amp;lt;/i&amp;gt;&lt;br /&gt;
* Added the feature for filtering out tasks in the table by including the filteredtasks component in the StudentTasksHome.tsx file. &lt;br /&gt;
* The corresponding formatting for the same included in the StudentTasks.module.css file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;4. Error and Edge Case Handling:&amp;lt;/b&amp;gt; Comprehensive error handling and edge case handling strategies were implemented to provide informative feedback for failed requests or empty datasets.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;5. Responsive and Accessible Design:&amp;lt;/b&amp;gt; The page implemented is fully responsive on all devices (desktop, tablet, mobile) and meets accessibility standards, including ARIA roles, ensuring a seamless and inclusive experience for all students, regardless of their device or abilities.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;6. Testing and Validation:&amp;lt;/b&amp;gt; The testing phase of the project involves a manual testing process to ensure the student task view list functions reliably.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Implementation Steps&amp;lt;/i&amp;gt;&lt;br /&gt;
*Carrying out a detailed manual review of each task item to confirm they display accurate information, ensuring visual indicators match the design specifications.&lt;br /&gt;
*Simulating user interactions manually to verify that component links and buttons function correctly, confirming that all elements respond as expected.&lt;br /&gt;
*Evaluating visual feedback elements like hover and active states to ensure they align with the project's usability standards.&lt;br /&gt;
&lt;br /&gt;
These steps are intended to confirm the interface's cohesive functionality and reliability by interacting with the system from an end-user perspective. This hands-on approach enables quick correction of any inconsistencies and improvements to the user experience.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Login page for accessing the system&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File: Login_Page_Student_tasks_UI.jpg | 1000px ]]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Navigate to the &amp;quot;Assignments&amp;quot; tab to view list of assignments&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File: New_Implementation_Assignments_Page.jpg | 1000px ]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; Legend&lt;br /&gt;
&lt;br /&gt;
We have included a legend on the right of the student task list, to improve clarity, allowing users to understand column meanings at a glance. This approach is more user-friendly than requiring users to hover over a small info icon, and it provides a cleaner, more streamlined interface.&lt;br /&gt;
&lt;br /&gt;
==Database==&lt;br /&gt;
We prepared the database by cloning and configuring the reimplementation backend, adhering to the guidelines provided in the Backend Setup Instructions. We will be creating dummy assignment data for testing purposes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; Sample of the Dummy data created &amp;lt;/b&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
[[File: Dummy_data_Student_Tasks_UI.jpg | 500px]]&lt;br /&gt;
&lt;br /&gt;
==Components==&lt;br /&gt;
*&amp;lt;b&amp;gt;App.tsx :&amp;lt;/b&amp;gt; The `App.tsx` file acts as the primary entry point for a React application, setting up routing, integrating various pages and components, and managing global states or contexts to enable seamless navigation and functionality across the app. We’ll be adding a protected route for &amp;quot;StudentTaskHome&amp;quot; to direct users with the STUDENT role to the `StudentTasksHome` component.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;StudentTasksBox.tsx :&amp;lt;/b&amp;gt; The StudentTaskbox.tsx file will display a sidebar component that emphasizes upcoming tasks, revisions, and team collaborations.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;StudentTaskHome.tsx :&amp;lt;/b&amp;gt; The StudentTaskHome.tsx file contains the main panel, presenting a comprehensive list of assignments with course information, topics, current stages, and other relevant details. This contains the dropdowns implemented in the main panel (table) for filtering based on the user's needs.&lt;br /&gt;
&lt;br /&gt;
==Files created/modified==&lt;br /&gt;
* src/App.tsx (Modified) - This file was changed to point to the new implementation of the Student Tasks page.&lt;br /&gt;
&lt;br /&gt;
* src/pages/StudentTasks/StudentTasksHome.tsx (New File) - This file was created to handle the content of task table in the Student Tasks page.&lt;br /&gt;
  &lt;br /&gt;
* src/pages/StudentTasks/StudentTaskBox.tsx (New File) - This file was created to handle the content of the yellow task box in the Student Tasks page.&lt;br /&gt;
&lt;br /&gt;
* src/pages/StudentTasks/StudentTasks.module.css (New File) - This file was created to handle the styling of the tasks table.&lt;br /&gt;
 &lt;br /&gt;
* src/pages/StudentTasks/StudentTasksBox.module.css (New File) - This file was created to handle the styling of the yellow task box.&lt;br /&gt;
&lt;br /&gt;
* src/pages/StudentTasks/testData.json (New File) - This file was created to store the dummy data for our implementation.&lt;br /&gt;
&lt;br /&gt;
==Design Patterns and Principles==&lt;br /&gt;
&lt;br /&gt;
Design patterns and principles are fundamental concepts that help developers create clean, scalable, and maintainable code. They guide the design of software structures and improve development efficiency, as they provide solutions to common problems and offer a vocabulary for communication within development teams. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Open/Closed Principle (OCP):&amp;lt;/b&amp;gt; Software entities should be open for extension but closed for modification, allowing new functionality without altering existing code. It ensures modularity and reusability, which aligns with the goal of designing React components for different sections of the Student Task List page. The existing code was just altered by adding additional features.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Don't Repeat Yourself (DRY):&amp;lt;/b&amp;gt;Avoid duplicating code. When functionality or logic repeats, it's better to refactor it into reusable functions, classes, or modules. The StudentTaskHome and StudentTasksBox components have all the required code and have been refactored to make it reusable.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Component Design and Structure:&amp;lt;/b&amp;gt; Design and organize React components to effectively support the Student Task List page, ensuring clarity and modularity.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Test Cases:&amp;lt;/i&amp;gt;&lt;br /&gt;
* Review the modular design of key components (e.g., header, task list, individual task items) for scalability and reusability.&lt;br /&gt;
* Check each component for proper structure and verify that all necessary information is displayed as expected.&lt;br /&gt;
* Confirm each component renders correctly within the overall page layout.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Task List Display:&amp;lt;/b&amp;gt; Implement functionality to accurately fetch and display assignments within the task list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Test Cases:&amp;lt;/i&amp;gt;&lt;br /&gt;
* Confirm that the task list properly renders each fetched assignment.&lt;br /&gt;
* Test for infinite scrolling, if needed, to handle extensive assignment lists smoothly.&lt;br /&gt;
* Verify that loading indicators or placeholders appear while data is loading, ensuring user feedback during fetch operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Filter Assignments:&amp;lt;/b&amp;gt; Ensure that the task list filters assignments to show only those relevant to the current user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Test Cases:&amp;lt;/i&amp;gt;&lt;br /&gt;
* Confirm the task list is correctly filtered based on the User ID, displaying only applicable assignments for the user.&lt;br /&gt;
&lt;br /&gt;
== Important Links ==&lt;br /&gt;
* GitHub repo [https://github.com/aditikilledar/reimplementation-front-end]&lt;br /&gt;
* Pull Request: [https://github.com/expertiza/reimplementation-front-end/pull/66]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=====Mentor===== &lt;br /&gt;
&lt;br /&gt;
* Chaitanya Srusti &amp;lt;crsrusti@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Members===== &lt;br /&gt;
* Aditi Killedar &amp;lt;akilled@ncsu.edu&amp;gt;&lt;br /&gt;
* Kruthi Rajeshwar &amp;lt;krajesh@ncsu.edu&amp;gt;&lt;br /&gt;
* Sphurthy Satish &amp;lt;sphurthy@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2463_Implement_Front_End_for_Student_Task_List&amp;diff=157354</id>
		<title>CSC/ECE 517 Fall 2024 - E2463 Implement Front End for Student Task List</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2463_Implement_Front_End_for_Student_Task_List&amp;diff=157354"/>
		<updated>2024-10-29T01:55:49Z</updated>

		<summary type="html">&lt;p&gt;Akilled: /* Current Implementation in Expertiza (Ruby on Rails) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Expertiza ==&lt;br /&gt;
Expertiza is an open-source learning management system primarily developed with Ruby on Rails. It offers features such as creating tests and assignments, managing teams and courses, and, most importantly, providing a robust framework for peer reviews and group feedback. This project focuses on developing frontend components in React, with an emphasis on the Student Task list page. The aim is to build a fully operational user interface for these components using React.js and TypeScript.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
The main objective of this project is to implement the front end for the Student Task list page within Expertiza.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
===Objective===&lt;br /&gt;
This project’s goal is to redesign the front end of the current non-TypeScript Student Task List page on Expertiza by building a new user interface with React.js and TypeScript, ensuring a more type-safe development experience. The page will showcase all assignments the user is involved in, requiring data fetching to obtain the assignment list, filtering based on the user’s participation, and presenting the results in a visually engaging, user-friendly format through React components.&lt;br /&gt;
This is the visual framework for creating the user interface:&lt;br /&gt;
&lt;br /&gt;
[[ | 1000px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Development Steps===&lt;br /&gt;
*&amp;lt;u&amp;gt;Review Current Interface&amp;lt;/u&amp;gt;:  Conduct a detailed analysis of the existing Ruby on Rails UI to understand its layout and features.&lt;br /&gt;
*&amp;lt;u&amp;gt;Setup Development Environment&amp;lt;/u&amp;gt;: Configure the environment to work with TypeScript and React.&lt;br /&gt;
*&amp;lt;u&amp;gt;Design Components&amp;lt;/u&amp;gt;: Break down the UI into distinct React components, defining the props and states needed for each.&lt;br /&gt;
*&amp;lt;u&amp;gt;Implement in Typescript&amp;lt;/u&amp;gt;: Develop the component logic in TypeScript, prioritizing type safety.&lt;br /&gt;
*&amp;lt;u&amp;gt;Replicate Functionality&amp;lt;/u&amp;gt;: Ensure all features from the Rails application are mirrored in the React components, maintaining full functionality.&lt;br /&gt;
*&amp;lt;u&amp;gt;Styling and Add Interactivity&amp;lt;/u&amp;gt;: Style components and integrate interactive elements using CSS.&lt;br /&gt;
*&amp;lt;u&amp;gt;Testing&amp;lt;/u&amp;gt;: Perform individual component testing and end-to-end testing for the entire application.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
===Current Implementation in Expertiza (Ruby on Rails)===&lt;br /&gt;
&lt;br /&gt;
The existing interface on Expertiza, developed with Ruby on Rails, displays a student's task list with assignments, due dates, and progress indicators.&lt;br /&gt;
&lt;br /&gt;
TODO: insert old implementation screenshot here.&lt;br /&gt;
&lt;br /&gt;
===New Implementation (React JS &amp;amp; TypeScript)===&lt;br /&gt;
&lt;br /&gt;
Our updated UI replicates the functionality of the original page, now leveraging TypeScript's reliability alongside React's dynamic rendering. We prioritized building a responsive, accessible interface that aligns with modern design principles. We have also included certain features to make it easy for the student to manage their assignments.&lt;br /&gt;
&amp;lt;b&amp;gt; Implementation Overview &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;b&amp;gt;Fetch and Display Data:&amp;lt;/b&amp;gt; The UI is designed with future live data integration in mind. Currently, we use structured placeholder data to mimic backend interactions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Implementation Steps&amp;lt;/i&amp;gt;&lt;br /&gt;
*Defined TypeScript interfaces to model assignment data structures.&lt;br /&gt;
*Created mock data to simulate API responses for development.&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;b&amp;gt;React Component Design:&amp;lt;/b&amp;gt; We developed modular React components like Header, TaskList, and TaskItem to improve code reusability and maintainability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Implementation Steps&amp;lt;/i&amp;gt;&lt;br /&gt;
==== StudentTasksBox component ====&lt;br /&gt;
*Definition of StudentTasksBox component with TypeScript props for type checking. - [ENTER LINK FOR THE LATEST COMMIT OF THE STUDENTTASKSBOX]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
const StudentTasksBox: React.FC&amp;lt;StudentTasksBoxProps&amp;gt; = ({ participantTasks, revisions, studentsTeamedWith }) =&amp;gt; {&lt;br /&gt;
    // Calculate total number of students teamed up with by iterating over each semester&lt;br /&gt;
    let totalStudents = 0;&lt;br /&gt;
    let allStudents: string[] = [];&lt;br /&gt;
    for (const semester in studentsTeamedWith) {&lt;br /&gt;
        // Add the number of students in each semester to the total count&lt;br /&gt;
        totalStudents += studentsTeamedWith[semester].length;&lt;br /&gt;
        allStudents = allStudents.concat(studentsTeamedWith[semester]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Calculate the number of revisions that are still pending (i.e., due date is in the future)&lt;br /&gt;
    const pendingRevisions = revisions.filter(revision =&amp;gt; getDaysLeft(revision.dueDate) &amp;gt; 0);&lt;br /&gt;
&lt;br /&gt;
    const dueTasks = participantTasks.filter(task =&amp;gt; getDaysLeft(task.stageDeadline) &amp;gt; 0);&lt;br /&gt;
&lt;br /&gt;
    // Group tasks by course&lt;br /&gt;
    const tasksByCourse: { [key: string]: typeof participantTasks } = {};&lt;br /&gt;
&lt;br /&gt;
    dueTasks.forEach(task =&amp;gt; {&lt;br /&gt;
        const courseName = task.course;&lt;br /&gt;
&lt;br /&gt;
        if (!tasksByCourse[courseName]) {&lt;br /&gt;
            tasksByCourse[courseName] = [];&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        tasksByCourse[courseName].push(task);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    return (&lt;br /&gt;
        &amp;lt;div className={styles.container}&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt;Task Summary&amp;lt;/h2&amp;gt;&lt;br /&gt;
            &amp;lt;div className={styles.infoBox}&amp;gt;&lt;br /&gt;
                &amp;lt;h5&amp;gt;Due:&amp;lt;/h5&amp;gt;&lt;br /&gt;
                {Object.entries(tasksByCourse).map(([course, tasks]) =&amp;gt; (&lt;br /&gt;
                    &amp;lt;div key={course}&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;{course}&amp;lt;/p&amp;gt;&lt;br /&gt;
                        &amp;lt;ul&amp;gt;&lt;br /&gt;
                            {tasks.map(task =&amp;gt; (&lt;br /&gt;
                                &amp;lt;li key={task.id}&amp;gt;&lt;br /&gt;
                                    {task.assignment} - Due: {task.stageDeadline}&lt;br /&gt;
                                &amp;lt;/li&amp;gt;&lt;br /&gt;
                            ))}&lt;br /&gt;
                        &amp;lt;/ul&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                ))}&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div className={styles.infoBox}&amp;gt;&lt;br /&gt;
                &amp;lt;h5&amp;gt;Revisions:&amp;lt;/h5&amp;gt;&lt;br /&gt;
                &amp;lt;ul&amp;gt;&lt;br /&gt;
                    {revisions.map((revision, index) =&amp;gt; (&lt;br /&gt;
                        &amp;lt;li key={index}&amp;gt;{revision.name}&amp;lt;/li&amp;gt;&lt;br /&gt;
                    ))}&lt;br /&gt;
                &amp;lt;/ul&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div className={styles.infoBox}&amp;gt;&lt;br /&gt;
                &amp;lt;div className={styles.teamedStudents}&amp;gt;&lt;br /&gt;
                    &amp;lt;h5&amp;gt;Total Students Teamed With: {totalStudents}&amp;lt;/h5&amp;gt;&lt;br /&gt;
                    &amp;lt;ul&amp;gt;&lt;br /&gt;
                        {allStudents.map((student, index) =&amp;gt; (&lt;br /&gt;
                            &amp;lt;li key={index}&amp;gt;{student}&amp;lt;/li&amp;gt;&lt;br /&gt;
                        ))}&lt;br /&gt;
                    &amp;lt;/ul&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;New UI for StudentTasksBox Component&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[ | 500px]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== StudentTasksHome component ====&lt;br /&gt;
*Creation of stateful StudentTasksHome component that handles list of assignments. [ENTER LINK FOR THE LATEST COMMIT OF THE STUDENTTASKSHOME]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
const StudentTasks: React.FC = () =&amp;gt; {&lt;br /&gt;
  // State and hooks initialization&lt;br /&gt;
  const participantTasks = testData.participantTasks;&lt;br /&gt;
  const currentUserId = testData.current_user_id;&lt;br /&gt;
  const auth = useSelector((state: RootState) =&amp;gt; state.authentication);&lt;br /&gt;
  const dispatch = useDispatch();&lt;br /&gt;
  const navigate = useNavigate();&lt;br /&gt;
&lt;br /&gt;
  // State to hold tasks&lt;br /&gt;
  const [tasks, setTasks] = useState&amp;lt;Task[]&amp;gt;([]);&lt;br /&gt;
  const exampleDuties = testData.dueTasks;&lt;br /&gt;
  const taskRevisions = testData.revisions;&lt;br /&gt;
  const studentsTeamedWith = testData.studentsTeamedWith;&lt;br /&gt;
&lt;br /&gt;
  // Effect to process tasks on component mount or update&lt;br /&gt;
  useEffect(() =&amp;gt; {&lt;br /&gt;
    if (participantTasks) {&lt;br /&gt;
      const filteredParticipantTasks = participantTasks.filter(task =&amp;gt; task.participant_id === currentUserId);&lt;br /&gt;
&lt;br /&gt;
      const mergedTasks = filteredParticipantTasks.map(task =&amp;gt; {&lt;br /&gt;
        return {&lt;br /&gt;
          id: task.id,&lt;br /&gt;
          assignment: task.assignment,&lt;br /&gt;
          course: task.course,&lt;br /&gt;
          topic: task.topic || '-',&lt;br /&gt;
          currentStage: task.current_stage || 'Pending',&lt;br /&gt;
          reviewGrade: task.review_grade || 'N/A',&lt;br /&gt;
          badges: task.badges || '',&lt;br /&gt;
          stageDeadline: task.stage_deadline || 'No deadline',&lt;br /&gt;
          publishingRights: task.publishing_rights || false&lt;br /&gt;
        };&lt;br /&gt;
      });&lt;br /&gt;
      setTasks(mergedTasks);&lt;br /&gt;
    }&lt;br /&gt;
  }, [participantTasks]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;New UI for StudentTasks Component&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
[[]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. &amp;lt;b&amp;gt;Table Filtering:&amp;lt;/b&amp;gt; The columns in the table are provided with filters enabling the user to search for what they want. The drop downs are provided for the columns: assignments, course, topic and current stage. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Implementation Steps&amp;lt;/i&amp;gt;&lt;br /&gt;
* Added the feature for filtering out tasks in the table by including the filteredtasks component in the StudentTasksHome.tsx file. &lt;br /&gt;
* The corresponding formatting for the same included in the StudentTasks.module.css file.&lt;br /&gt;
&lt;br /&gt;
4. &amp;lt;b&amp;gt;Error and Edge Case Handling:&amp;lt;/b&amp;gt; Comprehensive error handling and edge case handling strategies were implemented to provide informative feedback for failed requests or empty datasets.&lt;br /&gt;
&lt;br /&gt;
5. &amp;lt;b&amp;gt;Testing and Validation:&amp;lt;/b&amp;gt; The testing phase of the project involves a manual testing process to ensure the student task view list functions reliably.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Implementation Steps&amp;lt;/i&amp;gt;&lt;br /&gt;
* Perfoming Integrations tests to see if the iimplemented UI is able to interact with the live data which is currently in Expertiza database.&lt;br /&gt;
*Carrying out a detailed manual review of each task item to confirm they display accurate information, ensuring visual indicators match the design specifications.&lt;br /&gt;
*Simulating user interactions manually to verify that component links and buttons function correctly, confirming that all elements respond as expected.&lt;br /&gt;
*Evaluating visual feedback elements like hover and active states to ensure they align with the project's usability standards.&lt;br /&gt;
&lt;br /&gt;
These steps are intended to confirm the interface's cohesive functionality and reliability by interacting with the system from an end-user perspective. This hands-on approach enables quick correction of any inconsistencies and improvements to the user experience.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;b&amp;gt;Login page for accessing the system&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;[[]]&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;b&amp;gt;Navigate to the &amp;quot;Assignments&amp;quot; tab to view list of assignments&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;[[]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Database==&lt;br /&gt;
We prepared the database by cloning and configuring the reimplementation backend, adhering to the guidelines provided in the Backend Setup Instructions. We will be creating dummy assignment data for testing purposes.&lt;br /&gt;
&lt;br /&gt;
==Components==&lt;br /&gt;
*&amp;lt;b&amp;gt;App.tsx :&amp;lt;/b&amp;gt; The `App.tsx` file acts as the primary entry point for a React application, setting up routing, integrating various pages and components, and managing global states or contexts to enable seamless navigation and functionality across the app. We’ll be adding a protected route for &amp;quot;StudentTaskHome&amp;quot; to direct users with the STUDENT role to the `StudentTasksHome` component.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;StudentTasksBox.tsx :&amp;lt;/b&amp;gt; The StudentTaskbox.tsx file will display a sidebar component that emphasizes upcoming tasks, revisions, and team collaborations.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;StudentTasksHome.tsx :&amp;lt;/b&amp;gt; The StudentTasksHome.tsx file contains the main panel, presenting a comprehensive list of assignments with course information, topics, current stages, and other relevant details. This contains the dropdowns implemented in the main panel (table) for filtering based on the user's needs.&lt;br /&gt;
&lt;br /&gt;
==Files created/modified==&lt;br /&gt;
* src/App.tsx&lt;br /&gt;
&lt;br /&gt;
* src/pages/StudentTasks/StudentTasksHome.tsx (New File)&lt;br /&gt;
  &lt;br /&gt;
* src/pages/StudentTasks/StudentTaskBox.tsx (New File)&lt;br /&gt;
&lt;br /&gt;
* src/pages/StudentTasks/StudentTasks.module.css (New File)&lt;br /&gt;
 &lt;br /&gt;
* src/pages/StudentTasks/StudentTasksBox.module.css (New File)&lt;br /&gt;
&lt;br /&gt;
* src/pages/StudentTasks/testData.json (New File)&lt;br /&gt;
&lt;br /&gt;
==Design Patterns and Principles==&lt;br /&gt;
&lt;br /&gt;
Design patterns and principles are fundamental concepts that help developers create clean, scalable, and maintainable code. They guide the design of software structures and improve development efficiency, as they provide solutions to common problems and offer a vocabulary for communication within development teams. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Open/Closed Principle (OCP):&amp;lt;/b&amp;gt; Software entities should be open for extension but closed for modification, allowing new functionality without altering existing code. It ensures modularity and reusability, which aligns with the goal of designing React components for different sections of the Student Task List page. The existing code was just altered by adding additional features.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Don't Repeat Yourself (DRY):&amp;lt;/b&amp;gt;Avoid duplicating code. When functionality or logic repeats, it's better to refactor it into reusable functions, classes, or modules. The StudentTaskHome and StudentTasksBox components have all the required code and have been refactored to make it reusable.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;1. Component Design and Structure:&amp;lt;/b&amp;gt; Design and organize React components to effectively support the Student Task List page, ensuring clarity and modularity.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Test Cases:&amp;lt;/i&amp;gt;&lt;br /&gt;
* Review the modular design of key components (e.g., header, task list, individual task items) for scalability and reusability.&lt;br /&gt;
* Check each component for proper structure and verify that all necessary information is displayed as expected.&lt;br /&gt;
* Confirm each component renders correctly within the overall page layout.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;2. Task List Display:&amp;lt;/b&amp;gt; Implement functionality to accurately fetch and display assignments within the task list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Test Cases:&amp;lt;/i&amp;gt;&lt;br /&gt;
* Confirm that the task list properly renders each fetched assignment.&lt;br /&gt;
* Test for pagination or infinite scrolling, if needed, to handle extensive assignment lists smoothly.&lt;br /&gt;
* Verify that loading indicators or placeholders appear while data is loading, ensuring user feedback during fetch operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;3. Filter Assignments:&amp;lt;/b&amp;gt; Ensure that the task list filters assignments to show only those relevant to the current user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;Test Cases:&amp;lt;/i&amp;gt;&lt;br /&gt;
* Confirm the task list is correctly filtered based on the User ID, displaying only applicable assignments for the user.&lt;br /&gt;
&lt;br /&gt;
== Important Links ==&lt;br /&gt;
* GitHub repo [https://github.com/aditikilledar/reimplementation-front-end]&lt;br /&gt;
* Forked From: [https://github.com/expertiza/reimplementation-front-end]&lt;br /&gt;
* Demo video: []&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=====Mentor===== &lt;br /&gt;
&lt;br /&gt;
* Chaitanya Srusti &amp;lt;crsrusti@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Members===== &lt;br /&gt;
* Aditi Killedar &amp;lt;akilled@ncsu.edu&amp;gt;&lt;br /&gt;
* Kruthi Rajeshwar &amp;lt;krajesh@ncsu.edu&amp;gt;&lt;br /&gt;
* Sphurthy Satish &amp;lt;sphurthy@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akilled</name></author>
	</entry>
</feed>