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