Skip to main content

headless_lms_server/programs/seed/seed_courses/
seed_course_with_peer_review.rs

1use crate::programs::seed::builder::chapter::ChapterBuilder;
2use crate::programs::seed::builder::context::SeedContext;
3use crate::programs::seed::builder::course::{CourseBuilder, CourseInstanceConfig};
4use crate::programs::seed::builder::exercise::{ExerciseBuilder, ExerciseIds};
5use crate::programs::seed::builder::module::ModuleBuilder;
6use crate::programs::seed::builder::page::PageBuilder;
7use crate::programs::seed::seed_courses::CommonCourseData;
8use crate::programs::seed::seed_helpers::paragraph;
9use anyhow::Result;
10use chrono::Utc;
11
12use headless_lms_base::config::ApplicationConfiguration;
13use headless_lms_models::peer_or_self_review_configs::{
14    CmsPeerOrSelfReviewConfig, PeerReviewProcessingStrategy,
15};
16use headless_lms_models::peer_or_self_review_questions::CmsPeerOrSelfReviewQuestion;
17use headless_lms_models::roles::UserRole;
18use serde_json::json;
19use tracing::info;
20use uuid::Uuid;
21
22use super::super::seed_users::SeedUsersResult;
23
24#[allow(clippy::too_many_arguments)]
25pub async fn seed_peer_review_course(
26    app_config: &ApplicationConfiguration,
27    course_id: Uuid,
28    course_name: &str,
29    course_slug: &str,
30    common_course_data: CommonCourseData,
31    seed_users_result: SeedUsersResult,
32    flagged_answers_skip_manual_review_and_allow_retry: bool,
33    flagged_answers_threshold: Option<i32>,
34) -> Result<Uuid> {
35    let CommonCourseData {
36        db_pool,
37        organization_id: org,
38        teacher_user_id,
39        student_user_id: _student,
40        langs_user_id: _langs_user_id,
41        example_normal_user_ids: _users,
42        jwt_key: _jwt_key,
43        base_url: _base_url,
44    } = common_course_data;
45
46    let mut conn = db_pool.acquire().await?;
47    let cx = SeedContext {
48        teacher: teacher_user_id,
49        org,
50        base_course_ns: course_id,
51    };
52
53    info!("Inserting sample course {}", course_name);
54    let course = CourseBuilder::new(course_name, course_slug)
55        .desc("Sample course for testing reject and reset-feature in manual review after peer review.")
56        .chatbot(false)
57        .course_id(course_id)
58        .flagged_answers_skip_manual_review_and_allow_retry(flagged_answers_skip_manual_review_and_allow_retry)
59        .flagged_answers_threshold(flagged_answers_threshold)
60        .instance(CourseInstanceConfig {
61            name: None,
62            description: None,
63            support_email: None,
64            teacher_in_charge_name: "admin".to_string(),
65            teacher_in_charge_email: "admin@example.com".to_string(),
66            opening_time: None,
67            closing_time: None,
68            instance_id: Some(cx.v5(b"instance:default")),
69        })
70        .role(seed_users_result.teacher_user_id, UserRole::Teacher)
71        .module(
72            ModuleBuilder::new()
73                .order(0)
74                .register_to_open_university(false)
75                .automatic_completion(Some(1), Some(1), false)
76                .chapter(
77                    ChapterBuilder::new(1, "The Basics")
78                        .opens(Utc::now())
79                        .fixed_ids(cx.v5(b"chapter:1"), cx.v5(b"chapter:1:instance"))
80                        .page(
81                            PageBuilder::new("/chapter-1/page-1", "Page One")
82                                .block(paragraph(
83                                    "This is a simple introduction to the basics.",
84                                    cx.v5(b"page:1:1:block:intro"),
85                                ))
86                                .exercise(ExerciseBuilder::example_exercise(
87                                    "Simple multiple choice with peer review",
88                                    ExerciseIds {
89                                        exercise_id: cx.v5(b"exercise:1:1:e"),
90                                        slide_id: cx.v5(b"exercise:1:1:s"),
91                                        task_id: cx.v5(b"exercise:1:1:t"),
92                                        block_id: cx.v5(b"exercise:1:1:b"),
93                                    },
94                                    vec![paragraph(
95                                        "What is 2 + 2?",
96                                        cx.v5(b"exercise:1:1:prompt"),
97                                    )],
98                                    json!([
99                                        {
100                                            "name": "3",
101                                            "correct": false,
102                                            "id": cx.v5(b"exercise:1:1:option:1")
103                                        },
104                                        {
105                                            "name": "4",
106                                            "correct": true,
107                                            "id": cx.v5(b"exercise:1:1:option:2")
108                                        },
109                                        {
110                                            "name": "5",
111                                            "correct": false,
112                                            "id": cx.v5(b"exercise:1:1:option:3")
113                                        }
114                                    ]),
115                                    true,
116                                    Some(CmsPeerOrSelfReviewConfig {
117                                        id: cx.v5(b"peer-review:1"),
118                                        course_id,
119                                        exercise_id: Some(cx.v5(b"exercise:1:1:e")),
120                                        peer_reviews_to_give: 2,
121                                        peer_reviews_to_receive: 1,
122                                        accepting_threshold: 2.1,
123                                        processing_strategy:
124                                            PeerReviewProcessingStrategy::AutomaticallyGradeOrManualReviewByAverage,
125                                        reset_answer_if_zero_points_from_review: false,
126                                        points_are_all_or_nothing: true,
127                                        review_instructions: None,
128                                    }),
129                                    Some(vec![CmsPeerOrSelfReviewQuestion {
130                                        id: cx.v5(b"peer-review:1:q1"),
131                                        peer_or_self_review_config_id: cx.v5(b"peer-review:1"),
132                                        order_number: 1,
133                                        question: "Good answer?".to_string(),
134                                        question_type:
135                                            headless_lms_models::peer_or_self_review_questions::PeerOrSelfReviewQuestionType::Scale,
136                                        answer_required: true,
137                                        weight: 0.0,
138                                    }]),
139                                ))
140                                .exercise(ExerciseBuilder::example_exercise(
141                                    "Simple multiple choice with automatic reset on zero score",
142                                    ExerciseIds {
143                                        exercise_id: cx.v5(b"exercise:2:1:e"),
144                                        slide_id: cx.v5(b"exercise:2:1:s"),
145                                        task_id: cx.v5(b"exercise:2:1:t"),
146                                        block_id: cx.v5(b"exercise:2:1:b"),
147                                    },
148                                    vec![paragraph(
149                                        "What is 2 + 2?",
150                                        cx.v5(b"exercise:2:1:prompt"),
151                                    )],
152                                    json!([
153                                        {
154                                            "name": "3",
155                                            "correct": false,
156                                            "id": cx.v5(b"exercise:2:1:option:1")
157                                        },
158                                        {
159                                            "name": "4",
160                                            "correct": true,
161                                            "id": cx.v5(b"exercise:2:1:option:2")
162                                        },
163                                        {
164                                            "name": "5",
165                                            "correct": false,
166                                            "id": cx.v5(b"exercise:2:1:option:3")
167                                        }
168                                    ]),
169                                    true,
170                                    Some(CmsPeerOrSelfReviewConfig {
171                                        id: cx.v5(b"peer-review:2"),
172                                        course_id,
173                                        exercise_id: Some(cx.v5(b"exercise:2:1:e")),
174                                        peer_reviews_to_give: 2,
175                                        peer_reviews_to_receive: 1,
176                                        accepting_threshold: 2.1,
177                                        processing_strategy:
178                                            PeerReviewProcessingStrategy::AutomaticallyGradeByAverage,
179                                        reset_answer_if_zero_points_from_review: true,
180                                        points_are_all_or_nothing: true,
181                                        review_instructions: None,
182                                    }),
183                                    Some(vec![CmsPeerOrSelfReviewQuestion {
184                                        id: cx.v5(b"peer-review:2:q1"),
185                                        peer_or_self_review_config_id: cx.v5(b"peer-review:2"),
186                                        order_number: 1,
187                                        question: "Good answer?".to_string(),
188                                        question_type:
189                                            headless_lms_models::peer_or_self_review_questions::PeerOrSelfReviewQuestionType::Scale,
190                                        answer_required: true,
191                                        weight: 0.0,
192                                    }]),
193                                )),
194                        ),
195                ),
196        );
197    let (course, _default_instance, _last_module) = course.seed(&mut conn, app_config, &cx).await?;
198    Ok(course.id)
199}