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::{chatbot_block, heading, list, list_item, paragraph};
9use anyhow::Result;
10use chrono::Utc;
11
12use headless_lms_models::chatbot_configurations::NewChatbotConf;
13use headless_lms_models::roles::UserRole;
14use serde_json::json;
15
16use tracing::info;
17use uuid::Uuid;
18
19use super::super::seed_users::SeedUsersResult;
20
21pub async fn seed_chatbot_course(
22 course_id: Uuid,
23 course_name: &str,
24 course_slug: &str,
25 common_course_data: CommonCourseData,
26 seed_users_result: SeedUsersResult,
27) -> Result<Uuid> {
28 let CommonCourseData {
29 db_pool,
30 organization_id: org,
31 teacher_user_id,
32 student_user_id: _student,
33 langs_user_id: _langs_user_id,
34 example_normal_user_ids: _users,
35 jwt_key: _jwt_key,
36 base_url: _base_url,
37 } = common_course_data;
38
39 let mut conn = db_pool.acquire().await?;
40 let cx = SeedContext {
41 teacher: teacher_user_id,
42 org,
43 base_course_ns: course_id,
44 };
45
46 info!("Inserting sample course {}", course_name);
47
48 let course = CourseBuilder::new(course_name, course_slug)
49 .desc("Sample course for chatbot.")
50 .chatbot(true)
51 .course_id(course_id)
52 .instance(CourseInstanceConfig {
53 name: None,
54 description: None,
55 support_email: None,
56 teacher_in_charge_name: "admin".to_string(),
57 teacher_in_charge_email: "admin@example.com".to_string(),
58 opening_time: None,
59 closing_time: None,
60 instance_id: Some(cx.v5(b"instance:default")),
61 })
62 .chatbot_config(NewChatbotConf {
63 course_id,
64 chatbotconf_id: Some(cx.v5(b"chatbot_config:default")),
65 enabled_to_students: true,
66 chatbot_name: "Genetic Lifeform and Disk Operating System".to_string(),
67 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(),
68 initial_message: "Oh... It's you.".to_string(),
69 use_azure_search: true,
70 hide_citations: false,
71 default_chatbot: true,
72 ..Default::default()
73 })
74 .chatbot_config(NewChatbotConf {
75 course_id,
76 chatbotconf_id: Some(cx.v5(b"chatbot_config:block")),
77 enabled_to_students: true,
78 chatbot_name: "Test bot".to_string(),
79 prompt: "You are Test bot, a sophisticated AI tutoring assistant for Science education, equipped with a sharp wit and a subtly sarcastic tone...".to_string(),
80 initial_message: "Haiii xD What's up?".to_string(),
81 use_azure_search: true,
82 hide_citations: false,
83 ..Default::default()})
84 .role(seed_users_result.teacher_user_id, UserRole::Teacher)
85 .module(
86 ModuleBuilder::new()
87 .order(0)
88 .register_to_open_university(false)
89 .automatic_completion(Some(1), Some(1), false)
90 .chapter(
91 ChapterBuilder::new(1, "The Basics")
92 .opens(Utc::now())
93 .fixed_ids(cx.v5(b"chapter:1"), cx.v5(b"chapter:1:instance"))
94 .page(
95 PageBuilder::new("/chapter-1/page-1", "Page One")
96 .block(paragraph(
97 "This is a simple introduction to the basics.",
98 cx.v5(b"page:1:1:block:intro"),
99 ))
100 .exercise(ExerciseBuilder::example_exercise(
101 "Simple multiple choice",
102 ExerciseIds {
103 exercise_id: cx.v5(b"exercise:1:1:e"),
104 slide_id: cx.v5(b"exercise:1:1:s"),
105 task_id: cx.v5(b"exercise:1:1:t"),
106 block_id: cx.v5(b"exercise:1:1:b"),
107 },
108 vec![paragraph(
109 "What is 2 + 2?",
110 cx.v5(b"exercise:1:1:prompt"),
111 )],
112 json!([
113 {
114 "name": "3",
115 "correct": false,
116 "id": cx.v5(b"exercise:1:1:option:1")
117 },
118 {
119 "name": "4",
120 "correct": true,
121 "id": cx.v5(b"exercise:1:1:option:2")
122 },
123 {
124 "name": "5",
125 "correct": false,
126 "id": cx.v5(b"exercise:1:1:option:3")
127 }
128 ]),
129 )),
130 )
131 .page(
132 PageBuilder::new("/chapter-1/page-2", "Page 2")
133 .block(paragraph(
134 "Here you can prompt a chatbot.",
135 cx.v5(b"page:1:2:block:intro"),
136 ))
137 .block(chatbot_block(
138 cx.v5(b"page:1:2:block:chatbox"),
139 cx.v5(b"chatbot_config:block"),
140 course_id,
141 ))),
142 ),
143 )
144 .module(
145 ModuleBuilder::new()
146 .order(1)
147 .name("Another module")
148 .automatic_completion(Some(1), Some(1), false)
149 .ects(5.0)
150 .chapter(
151 ChapterBuilder::new(2, "Another chapter")
152 .fixed_ids(cx.v5(b"chapter:2"), cx.v5(b"chapter:2:instance"))
153 .page(PageBuilder::new("/chapter-2/page-1", "History of the abacus")
154 .block(heading("The History of the Abacus: Humanity's First Calculator", cx.v5(b"page:2:1:block:intro-heading"), 1))
155 .block(
156 paragraph(
157 "Long before the digital age and even before the invention of written numerals, humans needed a way to count, calculate, and trade. This necessity led to the creation of one of the world’s earliest and most enduring mathematical tools: the **abacus**. Often referred to as the **world's first calculator**, the abacus is not just a relic of the past but a symbol of human ingenuity in the pursuit of numerical understanding.",
158 cx.v5(b"page:2:1:block:intro"),
159 )
160 )
161 .block(
162 heading("Origins: The Dawn of Counting", cx.v5(b"page:2:1:block:origins-heading"), 2)
163 )
164 .block(
165 paragraph(
166 "The exact origins of the abacus are difficult to pinpoint due to the scarcity of early physical evidence. However, historians believe that the concept of the abacus evolved gradually as early humans transitioned from primitive counting methods—like tally marks and using fingers or stones—to more sophisticated systems.", cx.v5(b"page:2:1:block:origins"))
167 )
168 .block(
169 heading("Prehistoric Counting Tools", cx.v5(b"page:2:1:block:prehist-heading"), 3)
170 )
171 .block(paragraph(
172 "Before the invention of formal writing systems, humans used **counting boards**, **knotted ropes**, or lines drawn in the dirt to represent quantities. The **Ishango bone**, dated to around 20,000 years ago and found in Central Africa, features carved notches that some archaeologists believe represent a rudimentary counting system. While not an abacus in the traditional sense, it illustrates the human need to record and manipulate numbers.", cx.v5(b"page:2:1:block:prehist"),)
173 )
174 .block(
175 heading("The Mesopotamian and Egyptian Influence", cx.v5(b"page:2:1:block:meso-heading"), 2)
176 )
177 .block(paragraph(
178 "The **earliest true abacus-like devices** may have emerged in **Mesopotamia** around 2300 BCE. Sumerians used small pebbles or tokens (called **calculi**) on flat surfaces to perform basic arithmetic, especially for commerce and taxation. These were often used in conjunction with **clay tablets**, making them a precursor to what would become the abacus. Similarly, in **Ancient Egypt**, records suggest the use of counting boards with grooves and stones to assist in calculations. Although no physical abacuses from these periods survive, descriptions and artwork hint at their existence.", cx.v5(b"page:2:1:block:meso"),)
179 )
180 .block(
181 heading("The Greek and Roman Counting Boards", cx.v5(b"page:2:1:block:greek-heading"), 2)
182 )
183 .block(paragraph(
184 "By the 5th century BCE, the **Greeks** developed more advanced counting tools. One notable example is the **Salamis Tablet**, discovered on the Greek island of Salamis in 1846. Dating to around 300 BCE, this marble slab features carved lines and Greek numerals, suggesting it was used as a counting board or abacus. The **Romans** adopted and refined the Greek system. They developed portable versions made from bronze or wood, often with grooves and beads. The Roman abacus featured a **dual bead system**: one side represented units (ones, tens, hundreds), and the other represented fives, mirroring their base-10 numerical system with elements of base-5. This system allowed merchants and tax collectors to perform quick and efficient calculations.", cx.v5(b"page:2:1:block:greek"),)
185 )
186 .block(
187 heading("The Chinese Suanpan: A Milestone in Abacus Evolution", cx.v5(b"page:2:1:block:chinese-heading"), 2)
188 )
189 .block(paragraph(
190 "The **Chinese abacus**, known as the **suanpan (算盘)**, emerged around the 2nd century BCE during the Han Dynasty. Unlike earlier counting boards, the suanpan was a complete and portable device, consisting of a wooden frame with rods, each containing beads.", cx.v5(b"page:2:1:block:chinese"),)
191 )
192 .block(
193 heading("Structure and Use", cx.v5(b"page:2:1:block:stru-heading"), 3)
194 )
195 .block(list(cx.v5(b"page:2:1:block:stru-list"), false, vec![
196 list_item(cx.v5(b"page:2:1:block:stru-list1"), "The **traditional suanpan** has **two beads above** and **five beads below** a horizontal dividing bar (known as the beam)."),
197 list_item(cx.v5(b"page:2:1:block:stru-list2"), "Each rod represents a digit in a decimal place."),
198 list_item(cx.v5(b"page:2:1:block:stru-list3"), "Beads above the beam have a value of five; those below have a value of one."),
199 list_item(cx.v5(b"page:2:1:block:stru-list4"), "By moving the beads toward the beam, users could represent numbers and perform addition, subtraction, multiplication, division, and even extract square and cube roots."),
200 ])
201 )
202 .block(paragraph(
203 "The suanpan was widely used in Chinese society—from market stalls to imperial tax offices—and it became an essential part of Chinese education and commerce for centuries.", cx.v5(b"page:2:1:block:stru"),)
204 )
205 .block(
206 heading("The Japanese Soroban: Simplified Precision", cx.v5(b"page:2:1:block:japanese-heading"), 2)
207 )
208 .block(paragraph(
209 "The **Japanese soroban (そろばん)** was influenced by the Chinese suanpan and introduced to Japan around the 14th century. Over time, Japanese scholars and merchants refined the design, simplifying it for faster and more efficient calculation.", cx.v5(b"page:2:1:block:japanese"),)
210 )
211 .block(
212 heading("Key Differences", cx.v5(b"page:2:1:block:key-heading"), 3)
213 )
214 .block(list(cx.v5(b"page:2:1:block:key-list"), false, vec![
215 list_item(cx.v5(b"page:2:1:block:key-list1"), "The modern soroban typically has **one bead above** and **four beads below** the beam (a 1:4 configuration), unlike the 2:5 layout of the suanpan."),
216 list_item(cx.v5(b"page:2:1:block:key-list2"), "This change reflects the **decimal system** more clearly and allows easier mental calculations."),
217 list_item(cx.v5(b"page:2:1:block:key-list3"), "The soroban is smaller, more streamlined, and taught in schools even today as a mental math tool."),
218 ])
219 )
220 .block(paragraph(
221 "Japanese abacus masters, known as **soroban experts**, have been known to compete with electronic calculators—and sometimes win—in speed and accuracy contests.", cx.v5(b"page:2:1:block:key"),)
222 )
223 .block(
224 heading("The Russian Schoty: A Cultural Twist", cx.v5(b"page:2:1:block:russian-heading"), 2)
225 )
226 .block(paragraph(
227 "Another significant variant is the **Russian abacus**, or **schoty (счёты)**, developed in the 17th century. Unlike the Chinese and Japanese versions, the schoty is:", cx.v5(b"page:2:1:block:russian1"),)
228 )
229 .block(list(cx.v5(b"page:2:1:block:russian-list"), false, vec![
230 list_item(cx.v5(b"page:2:1:block:russian-list1"), "Used **horizontally**, not vertically."),
231 list_item(cx.v5(b"page:2:1:block:russian-list2"), "Has **10 beads per wire** (except for one wire with four for quarter-ruble calculations)."),
232 list_item(cx.v5(b"page:2:1:block:russian-list3"), "Operated using **one hand**, usually the right."),
233 list_item(cx.v5(b"page:2:1:block:russian-list4"), "Primarily used in Russian markets and accounting offices throughout the Soviet era.")])
234 )
235 .block(paragraph(
236 "The schoty reflects a different approach to abacus use but remains a powerful and intuitive calculator for those trained in its methods.", cx.v5(b"page:2:1:block:russian2"),)
237 )
238 .block(
239 heading("The Abacus in the Modern Era", cx.v5(b"page:2:1:block:modern-heading"), 2)
240 )
241 .block(paragraph(
242 "By the 17th century, the invention of **mechanical calculators** (such as Pascal's calculator) and later **electronic calculators** in the 20th century began to replace the abacus in many parts of the world. However, the abacus never truly disappeared.", cx.v5(b"page:2:1:block:modern"),)
243 )
244 .block(
245 heading("Contemporary Uses", cx.v5(b"page:2:1:block:conte-heading"), 3)
246 )
247 .block(
248 list(cx.v5(b"page:2:1:block:conte-list"), false, vec![list_item(cx.v5(b"page:2:1:block:conte-list1"), "In many Asian countries, especially **China, Japan, and Taiwan**, the abacus is still taught to schoolchildren."), list_item(cx.v5(b"page:2:1:block:conte-list2"), "It’s used to develop **mental arithmetic** skills, memory, and concentration."), list_item(cx.v5(b"page:2:1:block:conte-list3"), "Abacus competitions are held globally, where students perform lightning-fast calculations."), list_item(cx.v5(b"page:2:1:block:conte-list4"), "The abacus is also used as an educational tool for **visually impaired** students due to its tactile nature.")])
249 )
250 .block(
251 heading("The Abacus as a Cultural Icon", cx.v5(b"page:2:1:block:cultu-heading"), 2)
252 )
253 .block(paragraph(
254 "More than just a calculating device, the abacus has become a cultural symbol:", cx.v5(b"page:2:1:block:cultu"),)
255 )
256 .block(list(cx.v5(b"page:2:1:block:cultu-list"), false, vec![list_item(cx.v5(b"page:2:1:block:cultu-list1"), "In **Chinese culture**, the abacus symbolizes **wisdom and financial acumen**."), list_item(cx.v5(b"page:2:1:block:cultu-list2"), "In Japan, the soroban is associated with **discipline and mental strength**."), list_item(cx.v5(b"page:2:1:block:cultu-list3"), "The image of the abacus is often used in logos and iconography related to **mathematics, finance, and education**.")]))
257 .block(
258 heading("Conclusion: The Legacy of the Abacus", cx.v5(b"page:2:1:block:concl-heading"), 2)
259 )
260 .block(paragraph(
261 "The abacus has endured for thousands of years, evolving across continents and cultures. From Mesopotamian merchants to modern-day students mastering mental math, it has remained a testament to human creativity and the universal need to understand and manipulate numbers. In an age where technology continues to advance at lightning speed, the abacus reminds us that sometimes, the simplest tools can be the most profound. Whether made of beads, wood, or stone, the abacus is a bridge between the ancient and the modern—an enduring legacy of humankind’s quest for knowledge.", cx.v5(b"page:2:1:block:concl"),)
262 )
263 ),
264 ),
265 );
266
267 let (course, _default_instance, _last_module) = course.seed(&mut conn, &cx).await?;
268
269 Ok(course.id)
270}