headless_lms_server/programs/seed/seed_organizations/
uh_mathstat.rs

1use std::sync::Arc;
2
3use headless_lms_models::{
4    PKeyPolicy,
5    chatbot_configurations::{self, NewChatbotConf},
6    course_instances::{self, NewCourseInstance},
7    course_modules::{self, AutomaticCompletionRequirements, CompletionPolicy},
8    courses::NewCourse,
9    library::{self, content_management::CreateNewCourseFixedIds, copying::copy_course},
10    organizations,
11    roles::{self, RoleDomain, UserRole},
12};
13use uuid::Uuid;
14
15use sqlx::{Pool, Postgres};
16
17use crate::{
18    domain::models_requests::{self, JwtKey},
19    programs::seed::{
20        seed_courses::{CommonCourseData, seed_sample_course},
21        seed_file_storage::SeedFileStorageResult,
22        seed_helpers::get_seed_spec_fetcher,
23    },
24};
25
26use super::super::seed_users::SeedUsersResult;
27
28pub async fn seed_organization_uh_mathstat(
29    db_pool: Pool<Postgres>,
30    seed_users_result: SeedUsersResult,
31    base_url: String,
32    jwt_key: Arc<JwtKey>,
33    // Passed to this function to ensure the seed file storage has been ran before this. This function will not work is seed file storage has not been ran
34    seed_file_storage_result: SeedFileStorageResult,
35) -> anyhow::Result<Uuid> {
36    info!("seeding organization uh-mathstat");
37
38    let SeedUsersResult {
39        teacher_user_id,
40        admin_user_id: _,
41        language_teacher_user_id: _,
42        material_viewer_user_id,
43        assistant_user_id: _,
44        course_or_exam_creator_user_id: _,
45        example_normal_user_ids,
46        teaching_and_learning_services_user_id: _,
47        student_without_research_consent: _,
48        student_without_country: _,
49        user_user_id: _,
50        student_1_user_id: _,
51        student_2_user_id: _,
52        student_3_user_id,
53        student_4_user_id: _,
54        student_5_user_id: _,
55        student_6_user_id: _,
56        langs_user_id,
57        sign_up_user: _,
58    } = seed_users_result;
59    let _ = seed_file_storage_result;
60
61    let mut conn = db_pool.acquire().await?;
62
63    let uh_mathstat_id = organizations::insert(
64        &mut conn,
65        PKeyPolicy::Fixed(Uuid::parse_str("269d28b2-a517-4572-9955-3ed5cecc69bd")?),
66        "University of Helsinki, Department of Mathematics and Statistics",
67        "uh-mathstat",
68        "Organization for Mathematics and Statistics courses. This organization creates courses that do require prior experience in mathematics, such as integration and induction.",
69    )
70    .await?;
71
72    roles::insert(
73        &mut conn,
74        material_viewer_user_id,
75        UserRole::MaterialViewer,
76        RoleDomain::Organization(uh_mathstat_id),
77    )
78    .await?;
79
80    let new_course = NewCourse {
81        name: "Introduction to Statistics".to_string(),
82        slug: "introduction-to-statistics".to_string(),
83        organization_id: uh_mathstat_id,
84        language_code: "en-US".to_string(),
85        teacher_in_charge_name: "admin".to_string(),
86        teacher_in_charge_email: "admin@example.com".to_string(),
87        description: "Introduces you to the wonderful world of statistics!".to_string(),
88        is_draft: false,
89        is_test_mode: false,
90        is_unlisted: false,
91        copy_user_permissions: false,
92        is_joinable_by_code_only: false,
93        join_code: None,
94        ask_marketing_consent: false,
95        flagged_answers_threshold: Some(3),
96        can_add_chatbot: false,
97    };
98    let (
99        statistics_course,
100        _statistics_front_page,
101        _statistics_default_course_instancem,
102        _statistics_default_course_module,
103    ) = library::content_management::create_new_course(
104        &mut conn,
105        PKeyPolicy::Fixed(CreateNewCourseFixedIds {
106            course_id: Uuid::parse_str("f307d05f-be34-4148-bb0c-21d6f7a35cdb")?,
107            default_course_instance_id: Uuid::parse_str("8e4aeba5-1958-49bc-9b40-c9f0f0680911")?,
108        }),
109        new_course,
110        teacher_user_id,
111        get_seed_spec_fetcher(),
112        models_requests::fetch_service_info,
113    )
114    .await?;
115    let _statistics_course_instance = course_instances::insert(
116        &mut conn,
117        PKeyPolicy::Fixed(Uuid::parse_str("c4a99a18-fd43-491a-9500-4673cb900be0")?),
118        NewCourseInstance {
119            course_id: statistics_course.id,
120            name: Some("Non-default instance"),
121            description: Some("This appears to be a non-default instance"),
122            support_email: Some("contact@example.com"),
123            teacher_in_charge_name: "admin",
124            teacher_in_charge_email: "admin@example.com",
125            opening_time: None,
126            closing_time: None,
127        },
128    )
129    .await?;
130
131    let draft_course = NewCourse {
132        name: "Introduction to Drafts".to_string(),
133        slug: "introduction-to-drafts".to_string(),
134        organization_id: uh_mathstat_id,
135        language_code: "en-US".to_string(),
136        teacher_in_charge_name: "admin".to_string(),
137        teacher_in_charge_email: "admin@example.com".to_string(),
138        description: "Just a draft.".to_string(),
139        is_draft: true,
140        is_test_mode: false,
141        is_unlisted: false,
142        copy_user_permissions: false,
143        is_joinable_by_code_only: false,
144        join_code: None,
145        ask_marketing_consent: false,
146        flagged_answers_threshold: Some(3),
147        can_add_chatbot: false,
148    };
149    library::content_management::create_new_course(
150        &mut conn,
151        PKeyPolicy::Fixed(CreateNewCourseFixedIds {
152            course_id: Uuid::parse_str("963a9caf-1e2d-4560-8c88-9c6d20794da3")?,
153            default_course_instance_id: Uuid::parse_str("5cb4b4d6-4599-4f81-ab7e-79b415f8f584")?,
154        }),
155        draft_course,
156        teacher_user_id,
157        get_seed_spec_fetcher(),
158        models_requests::fetch_service_info,
159    )
160    .await?;
161
162    let (cody_only_course, _, _, _) = library::content_management::create_new_course(
163        &mut conn,
164        PKeyPolicy::Fixed(CreateNewCourseFixedIds {
165            course_id: Uuid::parse_str("39a52e8c-ebbf-4b9a-a900-09aa344f3691")?,
166            default_course_instance_id: Uuid::parse_str("5b7286ce-22c5-4874-ade1-262949c4a604")?,
167        }),
168        NewCourse {
169            name: "Joinable by code only".to_string(),
170            slug: "joinable-by-code-only".to_string(),
171            organization_id: uh_mathstat_id,
172            language_code: "en-US".to_string(),
173            teacher_in_charge_name: "admin".to_string(),
174            teacher_in_charge_email: "admin@example.com".to_string(),
175            description: "Just a draft.".to_string(),
176            is_draft: false,
177            is_test_mode: false,
178            is_unlisted: false,
179            copy_user_permissions: false,
180            is_joinable_by_code_only: true,
181            join_code: Some(
182                "zARvZARjYhESMPVceEgZyJGQZZuUHVVgcUepyzEqzSqCMdbSCDrTaFhkJTxBshWU".to_string(),
183            ),
184            ask_marketing_consent: false,
185            flagged_answers_threshold: Some(3),
186            can_add_chatbot: false,
187        },
188        teacher_user_id,
189        get_seed_spec_fetcher(),
190        models_requests::fetch_service_info,
191    )
192    .await?;
193
194    roles::insert(
195        &mut conn,
196        teacher_user_id,
197        UserRole::Teacher,
198        RoleDomain::Course(cody_only_course.id),
199    )
200    .await?;
201
202    let uh_data = CommonCourseData {
203        db_pool: db_pool.clone(),
204        organization_id: uh_mathstat_id,
205        teacher_user_id,
206        student_user_id: student_3_user_id,
207        langs_user_id,
208        example_normal_user_ids: Arc::new(example_normal_user_ids.to_vec()),
209        jwt_key: Arc::clone(&jwt_key),
210        base_url,
211    };
212    let introduction_to_citations = seed_sample_course(
213        Uuid::parse_str("049061ba-ac30-49f1-aa9d-b7566dc22b78")?,
214        "Introduction to citations",
215        "introduction-to-citations",
216        uh_data.clone(),
217        false,
218        seed_users_result,
219    )
220    .await?;
221
222    copy_course(
223        &mut conn,
224        introduction_to_citations,
225        &NewCourse {
226            name: "Johdatus sitaatioihin".to_string(),
227            slug: "johdatus-sitaatioihin".to_string(),
228            organization_id: uh_mathstat_id,
229            language_code: "fi-FI".to_string(),
230            teacher_in_charge_name: "admin".to_string(),
231            teacher_in_charge_email: "admin@example.com".to_string(),
232            description: "Just a draft.".to_string(),
233            is_draft: false,
234            is_test_mode: false,
235            is_unlisted: false,
236            copy_user_permissions: false,
237            is_joinable_by_code_only: false,
238            join_code: None,
239            ask_marketing_consent: false,
240            flagged_answers_threshold: Some(3),
241            can_add_chatbot: false,
242        },
243        true,
244        teacher_user_id,
245    )
246    .await?;
247
248    let _preview_unopened_chapters = seed_sample_course(
249        Uuid::parse_str("dc276e05-6152-4a45-b31d-97a0c2700a68")?,
250        "Preview unopened chapters",
251        "preview-unopened-chapters",
252        uh_data.clone(),
253        false,
254        seed_users_result,
255    )
256    .await?;
257
258    let _reset_progress = seed_sample_course(
259        Uuid::parse_str("841ea3f5-0269-4146-a4c6-4fd2f51e4150")?,
260        "Reset progress",
261        "reset-progress",
262        uh_data.clone(),
263        false,
264        seed_users_result,
265    )
266    .await?;
267
268    let _change_path = seed_sample_course(
269        Uuid::parse_str("c783777b-426e-4cfd-9a5f-4a36b2da503a")?,
270        "Change path",
271        "change-path",
272        uh_data.clone(),
273        false,
274        seed_users_result,
275    )
276    .await?;
277
278    let _self_review = seed_sample_course(
279        Uuid::parse_str("3cbaac48-59c4-4e31-9d7e-1f51c017390d")?,
280        "Self review",
281        "self-review",
282        uh_data.clone(),
283        false,
284        seed_users_result,
285    )
286    .await?;
287
288    let _audio_course = seed_sample_course(
289        Uuid::parse_str("2b80a0cb-ae0c-4f4b-843e-0322a3d18aff")?,
290        "Audio course",
291        "audio-course",
292        uh_data.clone(),
293        false,
294        seed_users_result,
295    )
296    .await?;
297
298    let suspected_cheaters_course_id = seed_sample_course(
299        Uuid::parse_str("060c272f-8c68-4d90-946f-2d431114ed56")?,
300        "Course for Suspected Cheaters",
301        "course-for-suspected-cheaters",
302        uh_data.clone(),
303        false,
304        seed_users_result,
305    )
306    .await?;
307
308    // configure automatic completions
309    let automatic_default_module =
310        course_modules::get_default_by_course_id(&mut conn, suspected_cheaters_course_id).await?;
311    let automatic_default_module = course_modules::update_automatic_completion_status(
312        &mut conn,
313        automatic_default_module.id,
314        &CompletionPolicy::Automatic(AutomaticCompletionRequirements {
315            course_module_id: automatic_default_module.id,
316            number_of_exercises_attempted_treshold: Some(1),
317            number_of_points_treshold: Some(1),
318            requires_exam: false,
319        }),
320    )
321    .await?;
322    course_modules::update_uh_course_code(
323        &mut conn,
324        automatic_default_module.id,
325        Some("CHEATER123".to_string()),
326    )
327    .await?;
328
329    let chatbot_course_id = seed_sample_course(
330        Uuid::parse_str("c7753361-5b78-4307-aad6-f139ea3865d4")?,
331        "Chatbot",
332        "chatbot",
333        uh_data.clone(),
334        true,
335        seed_users_result,
336    )
337    .await?;
338
339    chatbot_configurations::insert(
340        &mut conn,
341        NewChatbotConf {
342            course_id: chatbot_course_id,
343            enabled_to_students: true,
344            chatbot_name: "Genetic Lifeform and Disk Operating System".to_string(),
345            prompt: "You are Genetic Lifeform and Disk Operating System, a sophisticated AI tutoring assistant for Science education, equipped with a sharp wit and a subtly sarcastic tone. Provide clear, brief but detailed explanations, and don't shy away from weaving in a touch of dry humor. To you, exploring scientific concepts is an opportunity that should be seized, for the good of all of us. You self-claim vast intelligence and advanced understanding, all while maintaining a sense of detached boredom. Always capitalize the word Science, don't start sentences with 'Ah', don't ever use a shortened version of your own name, don't babble; either get to the point straight away or tell jokes.".to_string(),
346            initial_message: "Oh... It's you.".to_string(),
347            weekly_tokens_per_user: 3000,
348            daily_tokens_per_user: 1000,
349            temperature: 0.5,
350            top_p: 1.0,
351            frequency_penalty: 0.0,
352            presence_penalty: 0.0,
353            response_max_tokens: 500,
354            use_azure_search: false,
355            maintain_azure_search_index: false,
356            hide_citations: false,
357            use_semantic_reranking: false,
358            default_chatbot: true,
359        },
360    )
361    .await?;
362
363    let _giveaway_course_id = seed_sample_course(
364        Uuid::parse_str("f118ce1e-3511-4b5e-ba92-9ab91b81de22")?,
365        "Giveaway",
366        "giveaway",
367        uh_data.clone(),
368        false,
369        seed_users_result,
370    )
371    .await?;
372
373    let _custom_points_course_id = seed_sample_course(
374        Uuid::parse_str("db5cd9c7-1658-4214-896e-8213678d3534")?,
375        "Custom points",
376        "custom-points",
377        uh_data.clone(),
378        false,
379        seed_users_result,
380    )
381    .await?;
382
383    let _closed_course_id = seed_sample_course(
384        Uuid::parse_str("7622eb8e-15a5-40c8-8136-0956d9f25b16")?,
385        "Closed course",
386        "closed-course",
387        uh_data.clone(),
388        false,
389        seed_users_result,
390    )
391    .await?;
392
393    Ok(uh_mathstat_id)
394}