CSC/ECE 517 Fall 2025 - E2565. Integration of JoinTeamRequests: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
Line 9: Line 9:
Currently, Expertiza supports teammate advertisements for assignments with topics. Topic holders can create advertisements on the "Your Team" page. However, the complete flow for responding to advertisements and managing join team requests is not fully integrated. The following gaps exist:
Currently, Expertiza supports teammate advertisements for assignments with topics. Topic holders can create advertisements on the "Your Team" page. However, the complete flow for responding to advertisements and managing join team requests is not fully integrated. The following gaps exist:


# The join_team_requests_controller has action privilege checks scattered across methods instead of using a centralized `action_allowed?` method
1. The join_team_requests_controller has action privilege checks scattered across methods instead of using a centralized `action_allowed?` method
# There is no frontend UI for viewing advertisements on the Signup Sheet page
 
# There is no UI for creating join team requests when responding to advertisements
2. There is no frontend UI for viewing advertisements on the Signup Sheet page
# The "Received Requests" section is missing from the StudentTeamView page
 
# There is no method to accept join team requests (only decline exists)
3. There is no UI for creating join team requests when responding to advertisements
# The controller needs better integration with the frontend
 
4. The "Received Requests" section is missing from the StudentTeamView page
 
5. There is no method to accept join team requests (only decline exists)
 
6. The controller needs better integration with the frontend


=== Goals ===
=== Goals ===


# Refactor the join_team_requests_controller to use a single `action_allowed?` method for privilege checking
1. Refactor the join_team_requests_controller to use a single `action_allowed?` method for privilege checking
# Add a trumpet icon on the Signup Sheet page to indicate when advertisements exist for topics
 
# Create a frontend UI for viewing advertisements and creating join team requests
2. Add a trumpet icon on the Signup Sheet page to indicate when advertisements exist for topics
# Add a "Received Requests" section to StudentTeamView.tsx for managing incoming join team requests
 
# Implement an accept method for join team requests
3. Create a frontend UI for viewing advertisements and creating join team requests
# Ensure proper validation that teams cannot accept requests when full
 
# Conduct comprehensive testing of the entire flow
4. Add a "Received Requests" section to StudentTeamView.tsx for managing incoming join team requests
 
5. Implement an accept method for join team requests
 
6. Ensure proper validation that teams cannot accept requests when full
 
7. Conduct comprehensive testing of the entire flow


== Design ==
== Design ==
Line 370: Line 381:
=== Phase 1: Backend Refactoring ===
=== Phase 1: Backend Refactoring ===


# '''Refactor action_allowed? method'''
1. '''Refactor action_allowed? method'''
## Update `Api::V1::JoinTeamRequestsController#action_allowed?` to handle all actions
  a. Update `Api::V1::JoinTeamRequestsController#action_allowed?` to handle all actions
## Remove individual privilege checks from `index` method
  b. Remove individual privilege checks from `index` method
## Ensure all actions go through the centralized check
  c. Ensure all actions go through the centralized check
 
2. '''Add accept method'''
# '''Add accept method'''
  a. Implement `accept` method with team full validation
## Implement `accept` method with team full validation
  b. Add transaction handling for atomic operations
## Add transaction handling for atomic operations
  c. Update request status to ACCEPTED
## Update request status to ACCEPTED
  d. Add participant to team using `team.add_member`
## Add participant to team using `team.add_member`
3. '''Add team_requests method'''
 
  a. Implement method to fetch requests for a team
# '''Add team_requests method'''
  b. Add authorization check (user must be team member)
## Implement method to fetch requests for a team
  c. Include participant and user data in response
## Add authorization check (user must be team member)
4. '''Add advertisements method to SignedUpTeamsController'''
## Include participant and user data in response
  a. Implement method to fetch all advertisements for an assignment
 
  b. Join with teams and sign_up_topics
# '''Add advertisements method to SignedUpTeamsController'''
  c. Return formatted advertisement data
## Implement method to fetch all advertisements for an assignment
5. '''Update JoinTeamRequest model'''
## Join with teams and sign_up_topics
  a. Add `belongs_to :team` association
## Return formatted advertisement data
  b. Add scopes for filtering
 
  c. Update validations
# '''Update JoinTeamRequest model'''
6. '''Update routes'''
## Add `belongs_to :team` association
  a. Add routes for new endpoints
## Add scopes for filtering
  b. Ensure RESTful conventions
## Update validations
 
# '''Update routes'''
## Add routes for new endpoints
## Ensure RESTful conventions


=== Phase 2: Frontend - Signup Sheet ===
=== Phase 2: Frontend - Signup Sheet ===


# '''Create SignupSheet component (if not exists)'''
1. '''Create SignupSheet component (if not exists)'''
## Display topics for an assignment
  a. Display topics for an assignment
## Fetch advertisements for the assignment
  b. Fetch advertisements for the assignment
## Map advertisements to topics
  c. Map advertisements to topics
## Display trumpet icon for topics with advertisements
  d. Display trumpet icon for topics with advertisements
 
2. '''Create JoinTeamRequestModal component'''
# '''Create JoinTeamRequestModal component'''
  a. Design modal UI
## Design modal UI
  b. Implement form with comments field
## Implement form with comments field
  c. Add submit handler
## Add submit handler
  d. Handle success/error states
## Handle success/error states
3. '''Integrate modal with SignupSheet'''
 
  a. Add click handler for topics with advertisements
# '''Integrate modal with SignupSheet'''
  b. Open modal with advertisement details
## Add click handler for topics with advertisements
  c. Handle modal close
## Open modal with advertisement details
## Handle modal close


=== Phase 3: Frontend - StudentTeamView ===
=== Phase 3: Frontend - StudentTeamView ===


# '''Add Received Requests section'''
1. '''Add Received Requests section'''
## Create section similar to "Received Invitations"
  a. Create section similar to "Received Invitations"
## Fetch join team requests for current team
  b. Fetch join team requests for current team
## Display requests in table format
  c. Display requests in table format
 
2. '''Implement approve/decline functionality'''
# '''Implement approve/decline functionality'''
  a. Add approve button handler
## Add approve button handler
  b. Add decline button handler
## Add decline button handler
  c. Check team full status before allowing approve
## Check team full status before allowing approve
  d. Update UI after actions
## Update UI after actions
3. '''Add useJoinTeamRequest hook'''
 
  a. Create hook file
# '''Add useJoinTeamRequest hook'''
  b. Implement all API methods
## Create hook file
  c. Export hook for use in components
## Implement all API methods
## Export hook for use in components


=== Phase 4: Integration and Testing ===
=== Phase 4: Integration and Testing ===


# '''End-to-end testing'''
1. '''End-to-end testing'''
## Test advertisement creation → request creation → approval flow
  a. Test advertisement creation → request creation → approval flow
## Test decline flow
  b. Test decline flow
## Test team full validation
  c. Test team full validation
## Test authorization checks
  d. Test authorization checks
 
2. '''Unit testing'''
# '''Unit testing'''
  a. Test controller methods
## Test controller methods
  b. Test model validations
## Test model validations
  c. Test frontend components
## Test frontend components
3. '''Integration testing'''
 
  a. Test API endpoints
# '''Integration testing'''
  b. Test frontend-backend integration
## Test API endpoints
  c. Test error handling
## Test frontend-backend integration
## Test error handling


== Files Changed/Added ==
== Files Changed/Added ==
Line 492: Line 492:
==== Unit Tests ====
==== Unit Tests ====


# '''JoinTeamRequestsController Tests'''
1. '''JoinTeamRequestsController Tests'''
## Test action_allowed? for different actions and user roles
  a. Test action_allowed? for different actions and user roles
## Test accept method with valid request
  b. Test accept method with valid request
## Test accept method when team is full
  c. Test accept method when team is full
## Test accept method when participant already on team
  d. Test accept method when participant already on team
## Test team_requests method authorization
  e. Test team_requests method authorization
## Test team_requests method returns correct data
  f. Test team_requests method returns correct data
 
2. '''SignedUpTeamsController Tests'''
# '''SignedUpTeamsController Tests'''
  a. Test advertisements method returns correct data
## Test advertisements method returns correct data
  b. Test advertisements method filters correctly
## Test advertisements method filters correctly
3. '''JoinTeamRequest Model Tests'''
 
  a. Test associations
# '''JoinTeamRequest Model Tests'''
  b. Test validations
## Test associations
  c. Test scopes
## Test validations
## Test scopes


==== Integration Tests ====
==== Integration Tests ====


# '''End-to-End Flow Tests'''
1. '''End-to-End Flow Tests'''
## Create advertisement → Create join request → Accept request
  a. Create advertisement → Create join request → Accept request
## Create advertisement → Create join request → Decline request
  b. Create advertisement → Create join request → Decline request
## Test team full validation prevents acceptance
  c. Test team full validation prevents acceptance
## Test authorization prevents unauthorized access
  d. Test authorization prevents unauthorized access


=== Frontend Testing ===
=== Frontend Testing ===
Line 521: Line 519:
==== Component Tests ====
==== Component Tests ====


# '''SignUpSheet Component'''
1. '''SignUpSheet Component'''
## Test advertisement indicators display correctly
  a. Test advertisement indicators display correctly
## Test modal opens on click
  b. Test modal opens on click
## Test data fetching
  c. Test data fetching
 
2. '''JoinTeamRequestModal Component'''
# '''JoinTeamRequestModal Component'''
  a. Test form submission
## Test form submission
  b. Test validation
## Test validation
  c. Test success/error handling
## Test success/error handling
3. '''StudentTeamView Component'''
 
  a. Test Received Requests section displays
# '''StudentTeamView Component'''
  b. Test approve functionality
## Test Received Requests section displays
  c. Test decline functionality
## Test approve functionality
  d. Test team full validation
## Test decline functionality
## Test team full validation


==== Integration Tests ====
==== Integration Tests ====


# '''API Integration'''
1. '''API Integration'''
## Test all API calls work correctly
  a. Test all API calls work correctly
## Test error handling
  b. Test error handling
## Test loading states
  c. Test loading states


== Edge Cases and Error Handling ==
== Edge Cases and Error Handling ==
Line 548: Line 544:
=== Backend Edge Cases ===
=== Backend Edge Cases ===


# '''Team Full Validation'''
1. '''Team Full Validation'''
- Check team capacity before accepting request
  - Check team capacity before accepting request
- Return appropriate error message
  - Return appropriate error message
- Prevent race conditions with database transactions
  - Prevent race conditions with database transactions
 
2. '''Authorization'''
# '''Authorization'''
  - Verify user is team member before showing requests
- Verify user is team member before showing requests
  - Verify user is student before creating requests
- Verify user is student before creating requests
  - Verify user is administrator before viewing all requests
- Verify user is administrator before viewing all requests
3. '''Duplicate Requests'''
 
  - Prevent creating duplicate requests from same participant
# '''Duplicate Requests'''
  - Handle case where participant already on team
- Prevent creating duplicate requests from same participant
4. '''Concurrent Modifications'''
- Handle case where participant already on team
  - Use transactions for atomic operations
 
  - Handle race conditions in team membership updates
# '''Concurrent Modifications'''
- Use transactions for atomic operations
- Handle race conditions in team membership updates


=== Frontend Edge Cases ===
=== Frontend Edge Cases ===


# '''Network Errors'''
1. '''Network Errors'''
- Display appropriate error messages
  - Display appropriate error messages
- Handle timeout scenarios
  - Handle timeout scenarios
- Provide retry mechanisms
  - Provide retry mechanisms
 
2. '''Empty States'''
# '''Empty States'''
  - Show appropriate messages when no advertisements exist
- Show appropriate messages when no advertisements exist
  - Show appropriate messages when no requests exist
- Show appropriate messages when no requests exist
3. '''Loading States'''
 
  - Display loading indicators during API calls
# '''Loading States'''
  - Prevent multiple simultaneous requests
- Display loading indicators during API calls
4. '''Form Validation'''
- Prevent multiple simultaneous requests
  - Validate required fields
 
  - Provide user feedback for errors
# '''Form Validation'''
- Validate required fields
- Provide user feedback for errors


== Security Considerations ==
== Security Considerations ==


# '''Authorization Checks'''
1. '''Authorization Checks'''
- All endpoints must verify user permissions
  - All endpoints must verify user permissions
- Team members can only see requests for their team
  - Team members can only see requests for their team
- Students can only create requests for themselves
  - Students can only create requests for themselves
 
2. '''Input Validation'''
# '''Input Validation'''
  - Sanitize all user inputs
- Sanitize all user inputs
  - Validate team_id and assignment_id parameters
- Validate team_id and assignment_id parameters
  - Prevent SQL injection through parameterized queries
- Prevent SQL injection through parameterized queries
3. '''Rate Limiting'''
 
  - Consider rate limiting for request creation
# '''Rate Limiting'''
  - Prevent spam requests
- Consider rate limiting for request creation
- Prevent spam requests


== References ==
== References ==

Latest revision as of 02:43, 11 November 2025

E2565. Integration of JoinTeamRequests

Overview

This document describes the design and implementation plan for integrating JoinTeamRequests functionality in Expertiza. The feature enables students to respond to teammate advertisements by creating join team requests, which topic holders can then approve or decline. This integration will complete the teammate advertisement workflow by connecting the advertisement creation (already implemented) with the join team request flow.

Problem Statement

Currently, Expertiza supports teammate advertisements for assignments with topics. Topic holders can create advertisements on the "Your Team" page. However, the complete flow for responding to advertisements and managing join team requests is not fully integrated. The following gaps exist:

1. The join_team_requests_controller has action privilege checks scattered across methods instead of using a centralized `action_allowed?` method

2. There is no frontend UI for viewing advertisements on the Signup Sheet page

3. There is no UI for creating join team requests when responding to advertisements

4. The "Received Requests" section is missing from the StudentTeamView page

5. There is no method to accept join team requests (only decline exists)

6. The controller needs better integration with the frontend

Goals

1. Refactor the join_team_requests_controller to use a single `action_allowed?` method for privilege checking

2. Add a trumpet icon on the Signup Sheet page to indicate when advertisements exist for topics

3. Create a frontend UI for viewing advertisements and creating join team requests

4. Add a "Received Requests" section to StudentTeamView.tsx for managing incoming join team requests

5. Implement an accept method for join team requests

6. Ensure proper validation that teams cannot accept requests when full

7. Conduct comprehensive testing of the entire flow

Design

Backend Design

Controller Refactoring

The `Api::V1::JoinTeamRequestsController` currently has privilege checks scattered across methods:

- `index` method checks for administrator role directly - `action_allowed?` only checks if user is a student

Refactored Design:

The `action_allowed?` method will be enhanced to handle different actions based on the action being performed:

def action_allowed?
  case action_name.to_sym
  when :index
    @current_user.administrator?
  when :create, :show, :update, :destroy, :decline, :accept
    @current_user.student?
  else
    false
  end
end

All methods will rely on this centralized privilege check, removing individual checks from methods like `index`.

New Methods

1. Accept Method

Add a new `accept` method to handle accepting join team requests:

# PATCH/PUT api/v1/join_team_requests/:id/accept
# Accepts a join team request and adds the participant to the team
def accept
  team = @join_team_request.team
  
  # Check if team is full
  if team.full?
    return render json: { error: 'This team is full.' }, status: :unprocessable_entity
  end
  
  # Check if participant is already on the team
  if team.participants.include?(@join_team_request.participant)
    return render json: { error: 'Participant already belongs to the team' }, status: :unprocessable_entity
  end
  
  ActiveRecord::Base.transaction do
    # Add participant to team
    result = team.add_member(@join_team_request.participant)
    
    if result[:success]
      # Update request status
      @join_team_request.update!(reply_status: ACCEPTED)
      render json: { message: 'JoinTeamRequest accepted successfully', join_team_request: @join_team_request }, status: :ok
    else
      render json: { error: result[:error] }, status: :unprocessable_entity
      raise ActiveRecord::Rollback
    end
  end
rescue => e
  render json: { error: "Failed to accept request: #{e.message}" }, status: :unprocessable_entity
end

2. Get Join Team Requests for Team

Add a method to fetch all join team requests for a specific team (for the "Received Requests" section):

# GET api/v1/join_team_requests/team/:team_id
# Gets all join team requests for a specific team
def team_requests
  team = Team.find(params[:team_id])
  
  # Verify current user is a member of the team
  unless team.participants.exists?(user_id: @current_user.id)
    return render json: { error: 'Unauthorized' }, status: :unauthorized
  end
  
  join_team_requests = JoinTeamRequest.where(team_id: params[:team_id])
    .includes(:participant => :user)
    .order(created_at: :desc)
  
  render json: join_team_requests, status: :ok
end

3. Get Advertisements for Assignment

Add a method to fetch all advertisements for an assignment (for the Signup Sheet page):

# GET api/v1/signed_up_teams/advertisements/:assignment_id
# Gets all advertisements for an assignment
def advertisements
  assignment = Assignment.find(params[:assignment_id])
  signed_up_teams = SignedUpTeam.joins(:team, :sign_up_topic)
    .where(sign_up_topics: { assignment_id: params[:assignment_id] })
    .where(advertise_for_partner: true)
    .includes(:team, :sign_up_topic)
  
  advertisements = signed_up_teams.map do |sut|
    {
      id: sut.id,
      team_id: sut.team_id,
      team_name: sut.team.name,
      topic_id: sut.sign_up_topic_id,
      topic_name: sut.sign_up_topic.topic_name,
      comments_for_advertisement: sut.comments_for_advertisement,
      created_at: sut.created_at
    }
  end
  
  render json: advertisements, status: :ok
end

Model Updates

The `JoinTeamRequest` model needs to establish proper associations:

class JoinTeamRequest < ApplicationRecord
  belongs_to :team
  belongs_to :participant
  
  ACCEPTED_STATUSES = %w[ACCEPTED DECLINED PENDING]
  validates :reply_status, inclusion: { in: ACCEPTED_STATUSES }
  
  scope :pending, -> { where(reply_status: 'PENDING') }
  scope :for_team, ->(team_id) { where(team_id: team_id) }
end

Routes Updates

Add new routes for the additional endpoints:

resources :join_team_requests do
  collection do
    get 'team/:team_id', to: 'join_team_requests#team_requests'
    post 'decline/:id', to: 'join_team_requests#decline'
    post 'accept/:id', to: 'join_team_requests#accept'
  end
end

resources :signed_up_teams do
collection do
get 'advertisements/:assignment_id', to: 'signed_up_teams#advertisements'
end
member do
post :create_advertisement
patch :update_advertisement
delete :remove_advertisement
end
end

Frontend Design

Signup Sheet Page Enhancement

Create a new component or enhance existing signup sheet to display advertisements:

Component: SignupSheet.tsx

This component will:

- Display all topics for an assignment - Show a trumpet icon (🔔) next to topics that have advertisements - Allow users to click on topics with advertisements to view details - Provide a modal/dialog to view advertisement details and create a join team request

interface Advertisement {
  id: number;
  team_id: number;
  team_name: string;
  topic_id: number;
  topic_name: string;
  comments_for_advertisement: string;
  created_at: string;
}

interface SignUpTopic {
id: number;
topic_name: string;
topic_identifier: string;
max_choosers: number;
description?: string;
has_advertisement?: boolean;
advertisement?: Advertisement;
}

The UI will show:

- A table/list of topics - Trumpet icon indicator for topics with advertisements - Click handler to open advertisement details modal

Figure 1: Signup Sheet page showing trumpet icon indicators for topics with advertisements

Join Team Request Modal

Create a modal component for creating join team requests:

Component: JoinTeamRequestModal.tsx

This modal will:

- Display advertisement details (team name, topic, desired qualifications) - Provide a text area for comments (optional) - Show a "Send Request" button - Handle form submission and API calls

Figure 2: Modal displaying advertisement details with option to create join team request
interface JoinTeamRequestModalProps {
  show: boolean;
  onHide: () => void;
  advertisement: Advertisement;
  assignmentId: number;
  onSuccess: () => void;
}
Figure 3: Join team request creation form with advertisement details and comments field

StudentTeamView Enhancement

Add a "Received Requests" section to `StudentTeamView.tsx`:

Section: Received Join Team Requests

This section will:

- Display all pending join team requests for the current team - Show request details: requester name, email, comments, date - Provide "Approve" and "Decline" buttons for each request - Disable approve button if team is full - Show status for non-pending requests

interface JoinTeamRequest {
  id: number;
  participant_id: number;
  team_id: number;
  comments: string;
  reply_status: 'PENDING' | 'ACCEPTED' | 'DECLINED';
  created_at: string;
  participant: {
    id: number;
    user: {
      id: number;
      name: string;
      full_name: string;
      email: string;
    };
  };
}

The UI structure will be similar to the existing "Received Invitations" section, with:

- Table displaying request information - Action buttons (Approve/Decline) for pending requests - Status display for processed requests

Figure 4: Received Requests section in StudentTeamView showing all join team requests with approve/decline options

API Hooks

Create or extend hooks for join team requests:

File: hooks/useJoinTeamRequest.ts

export const useJoinTeamRequest = () => {
  const createRequestAPI = useAPI();
  const acceptRequestAPI = useAPI();
  const declineRequestAPI = useAPI();
  const fetchTeamRequestsAPI = useAPI();
  const fetchAdvertisementsAPI = useAPI();

const createJoinTeamRequest = (teamId: number, assignmentId: number, comments?: string) =>
createRequestAPI.sendRequest({
url: `/join_team_requests`,
method: 'POST',
data: { team_id: teamId, assignment_id: assignmentId, comments }
});

const acceptJoinTeamRequest = (requestId: number) =>
acceptRequestAPI.sendRequest({
url: `/join_team_requests/accept/${requestId}`,
method: 'POST'
});

const declineJoinTeamRequest = (requestId: number) =>
declineRequestAPI.sendRequest({
url: `/join_team_requests/decline/${requestId}`,
method: 'POST'
});

const fetchTeamRequests = (teamId: number) =>
fetchTeamRequestsAPI.sendRequest({
url: `/join_team_requests/team/${teamId}`
});

const fetchAdvertisements = (assignmentId: number) =>
fetchAdvertisementsAPI.sendRequest({
url: `/signed_up_teams/advertisements/${assignmentId}`
});

return {
createJoinTeamRequest,
acceptJoinTeamRequest,
declineJoinTeamRequest,
fetchTeamRequests,
fetchAdvertisements,
createRequestAPI,
acceptRequestAPI,
declineRequestAPI,
fetchTeamRequestsAPI,
fetchAdvertisementsAPI
};
};

Implementation Plan

Phase 1: Backend Refactoring

1. Refactor action_allowed? method

  a. Update `Api::V1::JoinTeamRequestsController#action_allowed?` to handle all actions
  b. Remove individual privilege checks from `index` method
  c. Ensure all actions go through the centralized check

2. Add accept method

  a. Implement `accept` method with team full validation
  b. Add transaction handling for atomic operations
  c. Update request status to ACCEPTED
  d. Add participant to team using `team.add_member`

3. Add team_requests method

  a. Implement method to fetch requests for a team
  b. Add authorization check (user must be team member)
  c. Include participant and user data in response

4. Add advertisements method to SignedUpTeamsController

  a. Implement method to fetch all advertisements for an assignment
  b. Join with teams and sign_up_topics
  c. Return formatted advertisement data

5. Update JoinTeamRequest model

  a. Add `belongs_to :team` association
  b. Add scopes for filtering
  c. Update validations

6. Update routes

  a. Add routes for new endpoints
  b. Ensure RESTful conventions

Phase 2: Frontend - Signup Sheet

1. Create SignupSheet component (if not exists)

  a. Display topics for an assignment
  b. Fetch advertisements for the assignment
  c. Map advertisements to topics
  d. Display trumpet icon for topics with advertisements

2. Create JoinTeamRequestModal component

  a. Design modal UI
  b. Implement form with comments field
  c. Add submit handler
  d. Handle success/error states

3. Integrate modal with SignupSheet

  a. Add click handler for topics with advertisements
  b. Open modal with advertisement details
  c. Handle modal close

Phase 3: Frontend - StudentTeamView

1. Add Received Requests section

  a. Create section similar to "Received Invitations"
  b. Fetch join team requests for current team
  c. Display requests in table format

2. Implement approve/decline functionality

  a. Add approve button handler
  b. Add decline button handler
  c. Check team full status before allowing approve
  d. Update UI after actions

3. Add useJoinTeamRequest hook

  a. Create hook file
  b. Implement all API methods
  c. Export hook for use in components

Phase 4: Integration and Testing

1. End-to-end testing

  a. Test advertisement creation → request creation → approval flow
  b. Test decline flow
  c. Test team full validation
  d. Test authorization checks

2. Unit testing

  a. Test controller methods
  b. Test model validations
  c. Test frontend components

3. Integration testing

  a. Test API endpoints
  b. Test frontend-backend integration
  c. Test error handling

Files Changed/Added

Backend Files

Modified:

- `app/controllers/api/v1/join_team_requests_controller.rb` - Refactor action_allowed?, add accept and team_requests methods - `app/controllers/api/v1/signed_up_teams_controller.rb` - Add advertisements method - `app/models/join_team_request.rb` - Add associations and scopes - `config/routes.rb` - Add new routes

Added:

- `spec/requests/api/v1/join_team_requests_spec.rb` - Request specs for new methods - `spec/models/join_team_request_spec.rb` - Model specs

Frontend Files

Modified:

- `src/pages/Student Teams/StudentTeamView.tsx` - Add Received Requests section - `src/hooks/useStudentTeam.ts` - Add join team request methods (or create new hook)

Added:

- `src/pages/SignUpSheet/SignUpSheet.tsx` - Signup sheet component with advertisement indicators - `src/pages/SignUpSheet/JoinTeamRequestModal.tsx` - Modal for creating join team requests - `src/hooks/useJoinTeamRequest.ts` - Hook for join team request API calls - `src/pages/SignUpSheet/SignUpSheet.module.css` - Styles for signup sheet - `src/pages/SignUpSheet/JoinTeamRequestModal.module.css` - Styles for modal

Testing Plan

Backend Testing

Unit Tests

1. JoinTeamRequestsController Tests

  a. Test action_allowed? for different actions and user roles
  b. Test accept method with valid request
  c. Test accept method when team is full
  d. Test accept method when participant already on team
  e. Test team_requests method authorization
  f. Test team_requests method returns correct data

2. SignedUpTeamsController Tests

  a. Test advertisements method returns correct data
  b. Test advertisements method filters correctly

3. JoinTeamRequest Model Tests

  a. Test associations
  b. Test validations
  c. Test scopes

Integration Tests

1. End-to-End Flow Tests

  a. Create advertisement → Create join request → Accept request
  b. Create advertisement → Create join request → Decline request
  c. Test team full validation prevents acceptance
  d. Test authorization prevents unauthorized access

Frontend Testing

Component Tests

1. SignUpSheet Component

  a. Test advertisement indicators display correctly
  b. Test modal opens on click
  c. Test data fetching

2. JoinTeamRequestModal Component

  a. Test form submission
  b. Test validation
  c. Test success/error handling

3. StudentTeamView Component

  a. Test Received Requests section displays
  b. Test approve functionality
  c. Test decline functionality
  d. Test team full validation

Integration Tests

1. API Integration

  a. Test all API calls work correctly
  b. Test error handling
  c. Test loading states

Edge Cases and Error Handling

Backend Edge Cases

1. Team Full Validation

  - Check team capacity before accepting request
  - Return appropriate error message
  - Prevent race conditions with database transactions

2. Authorization

  - Verify user is team member before showing requests
  - Verify user is student before creating requests
  - Verify user is administrator before viewing all requests

3. Duplicate Requests

  - Prevent creating duplicate requests from same participant
  - Handle case where participant already on team

4. Concurrent Modifications

  - Use transactions for atomic operations
  - Handle race conditions in team membership updates

Frontend Edge Cases

1. Network Errors

  - Display appropriate error messages
  - Handle timeout scenarios
  - Provide retry mechanisms

2. Empty States

  - Show appropriate messages when no advertisements exist
  - Show appropriate messages when no requests exist

3. Loading States

  - Display loading indicators during API calls
  - Prevent multiple simultaneous requests

4. Form Validation

  - Validate required fields
  - Provide user feedback for errors

Security Considerations

1. Authorization Checks

  - All endpoints must verify user permissions
  - Team members can only see requests for their team
  - Students can only create requests for themselves

2. Input Validation

  - Sanitize all user inputs
  - Validate team_id and assignment_id parameters
  - Prevent SQL injection through parameterized queries

3. Rate Limiting

  - Consider rate limiting for request creation
  - Prevent spam requests

References

- Expertiza Wiki: E2252. Refactor auth controller.rb & password retrieval controller.rb - Rails API Documentation - React Router Documentation - Expertiza Codebase: Existing invitation and team management implementations