headless_lms_models/
offered_answers_to_peer_review_temporary.rs1use rand::Rng;
2
3use crate::{exercise_slide_submissions::ExerciseSlideSubmission, prelude::*};
4
5pub async fn try_to_restore_previously_given_exercise_slide_submission(
8 conn: &mut PgConnection,
9 exercise_id: Uuid,
10 user_id: Uuid,
11 course_id: Uuid,
12) -> ModelResult<Option<ExerciseSlideSubmission>> {
13 if rand::rng().random_range(0..10) == 0 {
15 delete_expired_records(&mut *conn).await?;
16 }
17
18 let res = sqlx::query!(
19 "
20SELECT exercise_slide_submission_id
21FROM offered_answers_to_peer_review_temporary
22WHERE exercise_id = $1
23 AND user_id = $2
24 AND course_id = $3
25 AND created_at > now() - '1 hour'::interval
26 ",
27 exercise_id,
28 user_id,
29 course_id,
30 )
31 .fetch_optional(&mut *conn)
32 .await?;
33
34 if let Some(res) = res {
35 match crate::peer_review_queue_entries::get_by_receiving_peer_reviews_exercise_slide_submission_id(&mut *conn, res.exercise_slide_submission_id).await.optional()? { Some(peer_review_queue_entry) => {
37 if peer_review_queue_entry.received_enough_peer_reviews || peer_review_queue_entry.removed_from_queue_for_unusual_reason || peer_review_queue_entry.deleted_at.is_some() {
38 return Ok(None);
39 }
40 } _ => {
41 return Ok(None)
42 }}
43
44 let ess = crate::exercise_slide_submissions::get_by_id(
45 &mut *conn,
46 res.exercise_slide_submission_id,
47 )
48 .await?;
49
50 if ess.deleted_at.is_some() {
51 return Ok(None);
52 }
53 return Ok(Some(ess));
54 }
55 Ok(None)
56}
57
58pub async fn save_given_exercise_slide_submission(
60 conn: &mut PgConnection,
61 exercise_slide_submission_id: Uuid,
62 exercise_id: Uuid,
63 user_id: Uuid,
64 course_id: Uuid,
65) -> ModelResult<()> {
66 let _res = sqlx::query!(
67 "
68INSERT INTO offered_answers_to_peer_review_temporary (
69 exercise_slide_submission_id,
70 user_id,
71 course_id,
72 exercise_id
73 )
74VALUES ($1, $2, $3, $4) ON CONFLICT (user_id, exercise_id) DO
75UPDATE
76SET exercise_slide_submission_id = $1,
77 course_id = $3,
78 created_at = now()
79",
80 exercise_slide_submission_id,
81 user_id,
82 course_id,
83 exercise_id,
84 )
85 .execute(&mut *conn)
86 .await?;
87
88 Ok(())
89}
90
91pub async fn delete_saved_submissions_for_user(
93 conn: &mut PgConnection,
94 exercise_id: Uuid,
95 user_id: Uuid,
96) -> ModelResult<()> {
97 info!("Deleting expired records from offered_answers_to_peer_review_temporary");
98 let _res = sqlx::query!(
99 "
100DELETE FROM offered_answers_to_peer_review_temporary
101WHERE exercise_id = $1
102 AND user_id = $2
103",
104 exercise_id,
105 user_id
106 )
107 .execute(&mut *conn)
108 .await?;
109 Ok(())
110}
111
112async fn delete_expired_records(conn: &mut PgConnection) -> ModelResult<()> {
114 info!("Deleting expired records from offered_answers_to_peer_review_temporary");
115 let _res = sqlx::query!(
116 "
117DELETE FROM offered_answers_to_peer_review_temporary
118WHERE created_at < now() - '1 hour'::interval
119"
120 )
121 .execute(&mut *conn)
122 .await?;
123 Ok(())
124}