headless_lms_server/controllers/main_frontend/courses/
chatbots.rs1use crate::prelude::*;
3
4use headless_lms_models::chatbot_configurations::NewChatbotConf;
5use models::chatbot_configurations::ChatbotConfiguration;
6
7#[instrument(skip(pool))]
9async fn get_chatbots(
10 course_id: web::Path<Uuid>,
11 pool: web::Data<PgPool>,
12 user: AuthUser,
13) -> ControllerResult<web::Json<Vec<ChatbotConfiguration>>> {
14 let mut conn = pool.acquire().await?;
15 let token = authorize(&mut conn, Act::Edit, Some(user.id), Res::Course(*course_id)).await?;
16
17 let configurations =
18 models::chatbot_configurations::get_for_course(&mut conn, *course_id).await?;
19 token.authorized_ok(web::Json(configurations))
20}
21
22#[instrument(skip(pool, payload))]
24async fn create_chatbot(
25 course_id: web::Path<Uuid>,
26 payload: web::Json<String>,
27 pool: web::Data<PgPool>,
28 user: AuthUser,
29) -> ControllerResult<web::Json<ChatbotConfiguration>> {
30 let mut conn = pool.acquire().await?;
31 let token = authorize(&mut conn, Act::Edit, Some(user.id), Res::Course(*course_id)).await?;
32 let mut tx = conn.begin().await?;
33
34 let course = models::courses::get_course(&mut tx, *course_id).await?;
35
36 if !course.can_add_chatbot {
37 return Err(ControllerError::new(
38 ControllerErrorType::BadRequest,
39 "Course doesn't allow creating chatbots.".to_string(),
40 None,
41 ));
42 }
43
44 let model = models::chatbot_configurations_models::get_default(&mut tx)
45 .await
46 .map_err(|e| {
47 ControllerError::new(
48 ControllerErrorType::BadRequest,
49 "No default chatbot model configured. Ask an admin to set one.".to_string(),
50 Some(e.into()),
51 )
52 })?;
53
54 let configuration = models::chatbot_configurations::insert(
55 &mut tx,
56 PKeyPolicy::Generate,
57 NewChatbotConf {
58 chatbot_name: payload.into_inner(),
59 course_id: *course_id,
60 model_id: model.id,
61 thinking_model: model.thinking,
62 ..Default::default()
63 },
64 )
65 .await?;
66 tx.commit().await?;
67
68 token.authorized_ok(web::Json(configuration))
69}
70
71#[instrument(skip(pool))]
73async fn set_default_chatbot(
74 ids: web::Path<(Uuid, Uuid)>,
75 pool: web::Data<PgPool>,
76 user: AuthUser,
77) -> ControllerResult<web::Json<ChatbotConfiguration>> {
78 let mut conn = pool.acquire().await?;
79 let (course_id, chatbot_configuration_id) = *ids;
80
81 let token = authorize(&mut conn, Act::Edit, Some(user.id), Res::Course(course_id)).await?;
82 let mut tx = conn.begin().await?;
83
84 models::chatbot_configurations::remove_default_chatbot_from_course(&mut tx, course_id).await?;
85
86 let chatbot =
87 models::chatbot_configurations::get_by_id(&mut tx, chatbot_configuration_id).await?;
88
89 if course_id != chatbot.course_id {
90 return Err(ControllerError::new(
91 ControllerErrorType::BadRequest,
92 "Chatbot course id doesn't match the course id provided.".to_string(),
93 None,
94 ));
95 }
96
97 let configuration = models::chatbot_configurations::set_default_chatbot_for_course(
98 &mut tx,
99 chatbot_configuration_id,
100 )
101 .await?;
102 tx.commit().await?;
103
104 token.authorized_ok(web::Json(configuration))
105}
106
107#[instrument(skip(pool))]
109async fn set_non_default_chatbot(
110 ids: web::Path<(Uuid, Uuid)>,
111 pool: web::Data<PgPool>,
112 user: AuthUser,
113) -> ControllerResult<web::Json<ChatbotConfiguration>> {
114 let mut conn = pool.acquire().await?;
115 let (course_id, chatbot_configuration_id) = *ids;
116
117 let token = authorize(&mut conn, Act::Edit, Some(user.id), Res::Course(course_id)).await?;
118 let mut tx = conn.begin().await?;
119
120 models::chatbot_configurations::remove_default_chatbot_from_course(&mut tx, course_id).await?;
121
122 let configuration =
123 models::chatbot_configurations::get_by_id(&mut tx, chatbot_configuration_id).await?;
124
125 if course_id != configuration.course_id {
126 return Err(ControllerError::new(
127 ControllerErrorType::BadRequest,
128 "Chatbot course id doesn't match the course id provided.".to_string(),
129 None,
130 ));
131 }
132 tx.commit().await?;
133
134 token.authorized_ok(web::Json(configuration))
135}
136
137pub fn _add_routes(cfg: &mut web::ServiceConfig) {
138 cfg.route("", web::get().to(get_chatbots))
139 .route("", web::post().to(create_chatbot))
140 .route(
141 "/{chatbot_configuration_id}/set-as-default",
142 web::post().to(set_default_chatbot),
143 )
144 .route(
145 "/{chatbot_configuration_id}/set-as-non-default",
146 web::post().to(set_non_default_chatbot),
147 );
148}