Skip to content

Commit

Permalink
Users can't review answers that have exceeded the flagging threshold …
Browse files Browse the repository at this point in the history
…of the course
  • Loading branch information
Maija Y committed Jan 20, 2025
1 parent b5f8bdc commit 0e4e6bf
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 66 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 21 additions & 18 deletions services/headless-lms/models/src/exercise_slide_submissions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,24 +403,27 @@ pub async fn try_to_get_random_filtered_by_user_and_submissions(
ExerciseSlideSubmission,
r#"
SELECT DISTINCT ON (user_id)
id,
created_at,
updated_at,
deleted_at,
exercise_slide_id,
course_id,
course_instance_id,
exam_id,
exercise_id,
user_id,
user_points_update_strategy AS "user_points_update_strategy: _",
flag_count
FROM exercise_slide_submissions
WHERE exercise_id = $1
AND id <> ALL($2)
AND user_id <> $3
AND deleted_at IS NULL
ORDER BY user_id, created_at DESC
ess.id,
ess.created_at,
ess.updated_at,
ess.deleted_at,
ess.exercise_slide_id,
ess.course_id,
ess.course_instance_id,
ess.exam_id,
ess.exercise_id,
ess.user_id,
ess.user_points_update_strategy AS "user_points_update_strategy: _",
ess.flag_count
FROM exercise_slide_submissions AS ess
JOIN courses AS c
ON ess.course_id = c.id
WHERE ess.exercise_id = $1
AND ess.id <> ALL($2)
AND ess.user_id <> $3
AND ess.deleted_at IS NULL
AND ess.flag_count < c.flagged_answers_threshold
ORDER BY ess.user_id, ess.created_at DESC
"#,
exercise_id,
excluded_ids,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use crate::{
},
prelude::*,
};
use headless_lms_models::courses;
use headless_lms_models::exercise_slide_submissions::{self, NewFlaggedAnswer};
use headless_lms_models::user_exercise_states::CourseInstanceOrExamId;
use headless_lms_models::{courses, peer_review_queue_entries};
use models::{
exercise_task_submissions::PeerOrSelfReviewsReceived,
exercises::CourseMaterialExercise,
Expand Down Expand Up @@ -412,63 +412,82 @@ async fn post_flag_answer_in_peer_review(
let insert_result =
exercise_slide_submissions::insert_flagged_answer(&mut conn, new_flagged_answer).await;

//If the flagging was successful, increment the answers flag count and check if it needs to be moved to manual grading
if insert_result.is_err() {
if let Err(_) = insert_result {
return Err(ControllerError::new(
ControllerErrorType::InternalServerError,
"Failed to report answer".to_string(),
None,
));
} else {
let increment_flag_count =
exercise_slide_submissions::increment_flag_count(&mut conn, payload.submission_id)
.await;

if let Ok(updated_flag_count) = increment_flag_count {
let course = courses::get_course(&mut conn, course_id).await?;

if let Some(flagged_answers_threshold) = course.flagged_answers_threshold {
if updated_flag_count >= flagged_answers_threshold {
let course_instance_or_exam_id = if let Some(course_instance_id) =
flagged_submission_data.course_instance_id
{
CourseInstanceOrExamId::Instance(course_instance_id)
} else if let Some(exam_id) = flagged_submission_data.exam_id {
CourseInstanceOrExamId::Exam(exam_id)
} else {
return Err(ControllerError::new(
ControllerErrorType::InternalServerError,
"No course instance or exam ID found for the submission.".to_string(),
None,
));
};

let update_result = user_exercise_states::update_reviewing_stage(
&mut conn,
flagged_user,
course_instance_or_exam_id,
flagged_submission_data.exercise_id,
ReviewingStage::WaitingForManualGrading,
)
.await;

if update_result.is_err() {
return Err(ControllerError::new(
ControllerErrorType::InternalServerError,
"Failed to update the reviewing stage.".to_string(),
None,
));
}
}
}
}

// Increment the flag count
let updated_flag_count =
exercise_slide_submissions::increment_flag_count(&mut conn, payload.submission_id)
.await
.map_err(|_| {
ControllerError::new(
ControllerErrorType::InternalServerError,
"Failed to increment the flag count.".to_string(),
None,
)
})?;

let course = courses::get_course(&mut conn, course_id).await?;

// Check if the flag count exceeds the courses flagged answers threshold.
// If it does the move to manual review and remove from the peer review queue.
if let Some(flagged_answers_threshold) = course.flagged_answers_threshold {
if updated_flag_count < flagged_answers_threshold {
let token = skip_authorize();
return token.authorized_ok(web::Json(true));
}

let course_instance_id = flagged_submission_data
.course_instance_id
.map(CourseInstanceOrExamId::Instance)
.ok_or_else(|| {
ControllerError::new(
ControllerErrorType::InternalServerError,
"No course instance found for the submission.".to_string(),
None,
)
})?;

// Move the answer to manual review
let update_result = user_exercise_states::update_reviewing_stage(
&mut conn,
flagged_user,
course_instance_id,
flagged_submission_data.exercise_id,
ReviewingStage::WaitingForManualGrading,
)
.await?;

// Remove from peer review queue so other students can't review an answers that is already in manual review
if let Some(instance_id) = update_result.course_instance_id {
peer_review_queue_entries::remove_queue_entries_for_unusual_reason(
&mut conn,
flagged_user,
flagged_submission_data.exercise_id,
instance_id,
)
.await
.map_err(|_| {
ControllerError::new(
ControllerErrorType::InternalServerError,
"Failed to remove from the review queue.".to_string(),
None,
)
})?;
} else {
return Err(ControllerError::new(
ControllerErrorType::InternalServerError,
"Failed to increment the flag count.".to_string(),
"Failed to update the reviewing stage.".to_string(),
None,
));
}
}

let token = skip_authorize();
token.authorized_ok(web::Json(true))
}
Expand Down

0 comments on commit 0e4e6bf

Please sign in to comment.