Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
bf07582
due to compatiblity issue while setting up, we have to bump up puma v…
abhira0 Oct 25, 2025
79b1cfa
auto updated after running docker compose, but this happened because …
abhira0 Oct 25, 2025
646da19
updated the broken db/seeds.rb file, fixed the login problem
abhira0 Oct 25, 2025
5306624
Squashed commit of the following:
abhira0 Oct 25, 2025
2a84b20
fixed the issue with logging in
abhira0 Oct 26, 2025
bbb73e4
Refactor ProjectTopic and SignedUpTeam methods for clarity and consis…
Oct 26, 2025
10a6cdc
Merge branch 'main' of https://github.com/deekshithanantha/reimplemen…
Oct 26, 2025
bea6385
Refactor ProjectTopicsController and clean up schema.rb
Oct 27, 2025
8de3e25
Enhance ProjectTopicsController and SignedUpTeams functionality
srinidhis-code Oct 27, 2025
aab5d91
Refactor ProjectTopicsController and SignedUpTeamsController for impr…
srinidhis-code Oct 28, 2025
0b97d14
updaet dthe seed file to add project topics
abhira0 Oct 28, 2025
c9f4dbc
allow enabling bookmarks in the assignment edit
abhira0 Oct 28, 2025
e627fb8
udpated seeds to use faker
abhira0 Oct 30, 2025
8e1d078
allow more params while updating project topic
abhira0 Oct 30, 2025
91848b2
Refactor SignedUpTeam model and update seeds for improved team assign…
abhira0 Oct 30, 2025
eb67061
creating 5 students
abhira0 Oct 30, 2025
f9ee2fc
fixing tests
abhira0 Nov 11, 2025
11522f8
rewier database seed added
deekshithanantha Nov 20, 2025
94598fc
feat: Implement review grading, comments, and a review reports dashbo…
abhira0 Dec 3, 2025
1e084ff
feat: remove seeding of a specific multiple review test case
abhira0 Dec 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ruby-3.4.5
ruby-3.4.5
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ ruby '3.4.5'

gem 'mysql2', '~> 0.5.7'
gem 'sqlite3', '~> 1.4' # Alternative for development
gem 'puma', '~> 5.0'
gem 'puma', '~> 6.0'
gem 'rails', '~> 8.0', '>= 8.0.1'
gem 'mini_portile2', '~> 2.8' # Helps with native gem compilation
gem 'observer' # Required for Ruby 3.4.5 compatibility with Rails 8.0
Expand Down
36 changes: 33 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ GEM
term-ansicolor
thor
crass (1.0.6)
csv (3.3.5)
danger (9.5.3)
base64 (~> 0.2)
claide (~> 1.0)
Expand All @@ -128,6 +129,7 @@ GEM
debug (1.11.0)
irb (~> 1.10)
reline (>= 0.3.8)
delegate (0.4.0)
diff-lcs (1.6.2)
docile (1.4.1)
domain_name (0.6.20240107)
Expand All @@ -149,8 +151,11 @@ GEM
faraday (>= 0.8)
faraday-net_http (3.4.1)
net-http (>= 0.5.0)
faraday-retry (2.3.2)
faraday (~> 2.0)
find_with_order (1.3.1)
activerecord (>= 3)
forwardable (1.3.3)
git (2.3.3)
activesupport (>= 5.0)
addressable (~> 2.8)
Expand Down Expand Up @@ -197,10 +202,13 @@ GEM
mime-types-data (~> 3.2025, >= 3.2025.0507)
mime-types-data (3.2025.0924)
mini_mime (1.1.5)
mini_portile2 (2.8.9)
minitest (5.25.5)
mize (0.6.1)
monitor (0.2.0)
msgpack (1.8.0)
multi_json (1.17.0)
mutex_m (0.3.0)
mysql2 (0.5.7)
bigdecimal
nap (1.1.0)
Expand All @@ -217,7 +225,7 @@ GEM
net-protocol
netrc (0.11.0)
nio4r (2.5.9)
nokogiri (1.15.2-aarch64-linux)
nokogiri (1.18.10-aarch64-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.10-arm64-darwin)
racc (~> 1.4)
Expand All @@ -230,6 +238,7 @@ GEM
faraday (>= 1, < 3)
sawyer (~> 0.9)
open4 (1.3.4)
ostruct (0.6.3)
parallel (1.27.0)
parser (3.3.9.0)
ast (~> 2.4.1)
Expand Down Expand Up @@ -350,6 +359,7 @@ GEM
addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3)
securerandom (0.4.1)
set (1.1.2)
shoulda-matchers (6.5.0)
activesupport (>= 5.2.0)
simplecov (0.22.0)
Expand All @@ -358,7 +368,10 @@ GEM
simplecov_json_formatter (~> 0.1)
simplecov-html (0.13.2)
simplecov_json_formatter (0.1.4)
singleton (0.3.0)
spring (4.4.0)
sqlite3 (1.7.3)
mini_portile2 (~> 2.8.0)
stringio (3.1.7)
sync (0.5.0)
term-ansicolor (1.11.3)
Expand Down Expand Up @@ -398,18 +411,30 @@ PLATFORMS
DEPENDENCIES
active_model_serializers (~> 0.10.0)
bcrypt (~> 3.1.7)
bigdecimal
bootsnap (>= 1.18.4)
coveralls
csv
danger
database_cleaner-active_record
date
debug
delegate
factory_bot_rails
faker
faraday-retry
find_with_order
forwardable
jwt (~> 2.7, >= 2.7.1)
lingua
mysql2 (~> 0.5.5)
logger
mini_portile2 (~> 2.8)
monitor
mutex_m
mysql2 (~> 0.5.7)
observer
ostruct
psych (~> 5.2)
puma (~> 6.0)
rack-cors
rails (~> 8.0, >= 8.0.1)
Expand All @@ -418,14 +443,19 @@ DEPENDENCIES
rswag-specs
rswag-ui
rubocop
set
shoulda-matchers
simplecov
simplecov_json_formatter
singleton
spring
sqlite3 (~> 1.4)
timeout
tzinfo-data
uri

RUBY VERSION
ruby 3.2.7p253
ruby 3.4.5p51

BUNDLED WITH
2.4.14
4 changes: 2 additions & 2 deletions app/controllers/assignments_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ def show_assignment_details
end

# check if assignment has topics
# has_topics is set to true if there is SignUpTopic corresponding to the input assignment id
# has_topics is set to true if there is ProjectTopic corresponding to the input assignment id
def has_topics
assignment = Assignment.find_by(id: params[:assignment_id])
if assignment.nil?
Expand Down Expand Up @@ -213,7 +213,7 @@ def varying_rubrics_by_round?
private
# Only allow a list of trusted parameters through.
def assignment_params
params.require(:assignment).permit(:title, :description)
params.require(:assignment).permit(:title, :description, :allow_bookmarks)
end

# Helper method to determine staggered_and_no_topic for the assignment
Expand Down
71 changes: 71 additions & 0 deletions app/controllers/project_topics_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
class ProjectTopicsController < ApplicationController
before_action :set_project_topic, only: %i[ show update ]

# GET /project_topics?assignment_id=&topic_ids[]=
def index
if params[:assignment_id].nil?
render json: { message: 'Assignment ID is required!' }, status: :unprocessable_entity
else
@project_topics = ProjectTopic.find_by_assignment_and_topic_ids(params[:assignment_id], params[:topic_ids])
render json: @project_topics.map(&:to_json_with_computed_data), status: :ok
end
end

# POST /project_topics
def create
result = ProjectTopic.create_topic_with_assignment(
project_topic_params,
params[:project_topic][:assignment_id],
params[:micropayment]
)

if result[:success]
render json: { message: result[:message] }, status: :created
else
render json: { message: result[:message] }, status: :unprocessable_entity
end
end

# PATCH/PUT /project_topics/1
def update
result = @project_topic.update_topic(project_topic_params)

if result[:success]
render json: { message: result[:message] }, status: :ok
else
render json: { message: result[:message] }, status: :unprocessable_entity
end
end

# Show a ProjectTopic by ID
def show
render json: @project_topic, status: :ok
end

# Destroy ProjectTopics by assignment_id and optional topic_ids
def destroy
if params[:assignment_id].nil?
render json: { message: 'Assignment ID is required!' }, status: :unprocessable_entity
else
result = ProjectTopic.delete_by_assignment_and_topic_ids(params[:assignment_id], params[:topic_ids])

if result[:success]
render json: { message: result[:message] }, status: :no_content
else
render json: { message: result[:message] }, status: :unprocessable_entity
end
end
end

private

# Use callbacks to share common setup or constraints between actions.
def set_project_topic
@project_topic = ProjectTopic.find(params[:id])
end

# Only allow a list of trusted parameters through.
def project_topic_params
params.require(:project_topic).permit(:topic_identifier, :category, :topic_name, :max_choosers, :assignment_id, :description, :link)
end
end
98 changes: 98 additions & 0 deletions app/controllers/review_reports_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
class ReviewReportsController < ApplicationController
# GET /review_reports/:assignment_id
def index
assignment = Assignment.find(params[:assignment_id])
# Fetch all review response maps for this assignment
review_maps = ReviewResponseMap.where(reviewed_object_id: assignment.id)

report_data = review_maps.map do |map|
reviewer = map.reviewer.user
reviewee = map.reviewee # Team

# Get all responses
responses = Response.where(map_id: map.id).order(created_at: :asc)

rounds = responses.map do |response|
questionnaire = response.questionnaire_by_answer(response.scores.first)
assignment_questionnaire = AssignmentQuestionnaire.find_by(assignment_id: assignment.id, questionnaire_id: questionnaire.id)
round_num = assignment_questionnaire&.used_in_round || 1 # Default to 1 if not specified

{
round: round_num,
calculatedScore: response.aggregate_questionnaire_score,
maxScore: response.maximum_score,
reviewVolume: response.volume,
reviewCommentCount: response.comment_count
}
end

# Use the latest response for general status, but keep rounds data
latest_response = responses.last

# Calculate reviews done/selected
reviews_selected = 1
reviews_completed = latest_response&.is_submitted ? 1 : 0

# Calculate score (latest)
score = latest_response&.aggregate_questionnaire_score
max_score = latest_response&.maximum_score

# Calculate volume (latest)
vol = latest_response&.volume || 0

# Determine status color
status = if !latest_response
"purple" # No review
elsif !latest_response.is_submitted
"red" # Not completed
elsif latest_response.is_submitted && map.reviewer_grade.nil?
"blue" # Completed, no grade
elsif map.reviewer_grade
"brown" # Grade assigned
else
"green" # Fallback or specific case (No submitted work?)
end

{
id: map.id,
reviewerName: reviewer.full_name,
reviewerUsername: reviewer.name,
reviewerId: reviewer.id,
reviewsCompleted: reviews_completed,
reviewsSelected: reviews_selected,
teamReviewedName: reviewee.name,
hasConsent: map.reviewer.permission_granted,
teamReviewedStatus: status,
calculatedScore: score, # Latest score
maxScore: max_score, # Latest max score
rounds: rounds, # All rounds data
reviewComment: latest_response&.additional_comment,
reviewVolume: vol,
reviewCommentCount: latest_response&.comment_count || 0,
assignedGrade: map.reviewer_grade,
instructorComment: map.reviewer_comment
}
end

# Calculate average volume for the assignment
total_volume = report_data.sum { |d| d[:reviewVolume] }
count_volume = report_data.count { |d| d[:reviewVolume] > 0 }
avg_volume = count_volume > 0 ? total_volume.to_f / count_volume : 0

render json: {
reportData: report_data,
averageVolume: avg_volume
}
end

# PATCH /review_reports/:id/update_grade
# Updates the grade and comment for a specific review report
def update_grade
map = ReviewResponseMap.find(params[:id])
if map.update(reviewer_grade: params[:assignedGrade], reviewer_comment: params[:instructorComment])
render json: { message: "Grade updated successfully" }, status: :ok
else
render json: { error: "Failed to update grade" }, status: :unprocessable_entity
end
end
end
Loading
Loading