headless_lms_server/programs/seed/seed_courses/
seed_graded.rs1use crate::programs::seed::builder::certificate::CertificateBuilder;
2use crate::programs::seed::builder::chapter::ChapterBuilder;
3use crate::programs::seed::builder::context::SeedContext;
4use crate::programs::seed::builder::course::{CourseBuilder, CourseInstanceConfig};
5use crate::programs::seed::builder::module::{
6 CompletionBuilder, CompletionRegisteredBuilder, ModuleBuilder,
7};
8use crate::programs::seed::builder::page::PageBuilder;
9use crate::programs::seed::seed_courses::CommonCourseData;
10use crate::programs::seed::seed_helpers::paragraph;
11use anyhow::{Context, Result};
12use chrono::Utc;
13use headless_lms_base::config::ApplicationConfiguration;
14use headless_lms_models::certificate_configuration_to_requirements;
15use headless_lms_models::certificate_configurations::{
16 DatabaseCertificateConfiguration, insert as insert_certificate_configuration,
17};
18use headless_lms_models::course_instance_enrollments;
19use headless_lms_models::file_uploads;
20use headless_lms_models::roles::UserRole;
21use headless_lms_models::study_registry_registrars::get_or_create_default_registrar;
22use tracing::info;
23use uuid::Uuid;
24
25use super::super::seed_users::SeedUsersResult;
26
27pub async fn seed_graded_course(
28 app_config: ApplicationConfiguration,
29 course_id: Uuid,
30 course_name: &str,
31 course_slug: &str,
32 common_course_data: CommonCourseData,
33 seed_users_result: SeedUsersResult,
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,
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
55 let registrar_id = get_or_create_default_registrar(&mut conn).await?;
57
58 let mut module = ModuleBuilder::new()
59 .order(0)
60 .automatic_completion(Some(1), Some(1), false)
61 .default_registrar(registrar_id);
62
63 for (i, uid) in example_normal_user_ids.iter().enumerate() {
64 module = module.completion(
65 CompletionBuilder::new(*uid)
66 .grade(5)
67 .passed(true)
68 .registered(
69 CompletionRegisteredBuilder::new().real_student_number(format!("52-{:03}", i)),
70 ),
71 );
72 }
73
74 let course_builder = CourseBuilder::new(course_name, course_slug)
76 .desc("A sample graded course that pre-seeds module completions for demo users.")
77 .chatbot(false)
78 .course_id(course_id)
79 .instance(CourseInstanceConfig {
80 name: None,
81 description: None,
82 support_email: None,
83 teacher_in_charge_name: "admin".to_string(),
84 teacher_in_charge_email: "admin@example.com".to_string(),
85 opening_time: None,
86 closing_time: None,
87 instance_id: Some(cx.v5(b"instance:graded")),
88 })
89 .role(seed_users_result.teacher_user_id, UserRole::Teacher)
90 .module(
91 module.chapter(
92 ChapterBuilder::new(1, "The Basics")
93 .opens(Utc::now())
94 .fixed_ids(cx.v5(b"chapter:1"), cx.v5(b"chapter:1:instance"))
95 .page(
96 PageBuilder::new("/chapter-1/page-1", "Welcome").block(paragraph(
97 "This is the graded example course.",
98 cx.v5(b"page:1:1"),
99 )),
100 ),
101 ),
102 );
103
104 let (course, default_instance, last_module) =
106 course_builder.seed(&mut conn, &app_config, &cx).await?;
107
108 for uid in example_normal_user_ids.iter() {
110 course_instance_enrollments::insert(&mut conn, *uid, course.id, default_instance.id)
111 .await?;
112 }
113
114 let background_svg_path = "svgs/certificate-background.svg".to_string();
115
116 let background_svg_file_upload_id = file_uploads::insert(
117 &mut conn,
118 &format!("background-{}.svg", last_module.id),
119 &background_svg_path,
120 "image/svg+xml",
121 None,
122 None,
123 )
124 .await?;
125
126 let configuration = DatabaseCertificateConfiguration {
127 id: Uuid::new_v5(&course_id, b"graded-course-certificate-configuration"),
128 certificate_owner_name_y_pos: None,
129 certificate_owner_name_x_pos: None,
130 certificate_owner_name_font_size: None,
131 certificate_owner_name_text_color: None,
132 certificate_owner_name_text_anchor: None,
133 certificate_validate_url_y_pos: None,
134 certificate_validate_url_x_pos: None,
135 certificate_validate_url_font_size: None,
136 certificate_validate_url_text_color: None,
137 certificate_validate_url_text_anchor: None,
138 certificate_date_y_pos: None,
139 certificate_date_x_pos: None,
140 certificate_date_font_size: None,
141 certificate_date_text_color: None,
142 certificate_date_text_anchor: None,
143 certificate_locale: None,
144 paper_size: None,
145 background_svg_path,
146 background_svg_file_upload_id,
147 overlay_svg_path: None,
148 overlay_svg_file_upload_id: None,
149 render_certificate_grade: true,
150 certificate_grade_y_pos: None,
151 certificate_grade_x_pos: None,
152 certificate_grade_font_size: None,
153 certificate_grade_text_color: None,
154 certificate_grade_text_anchor: None,
155 };
156
157 let database_configuration = insert_certificate_configuration(&mut conn, &configuration)
158 .await
159 .context("insert certificate configuration")?;
160
161 certificate_configuration_to_requirements::insert(
162 &mut conn,
163 database_configuration.id,
164 Some(last_module.id),
165 )
166 .await?;
167
168 for uid in example_normal_user_ids.iter() {
170 CertificateBuilder::new(*uid)
171 .default_configuration_for_module(last_module.id)
172 .name_on_certificate(format!("Demo User {}", uid))
173 .seed(&mut conn)
174 .await?;
175 }
176
177 Ok(course_id)
178}