headless_lms_chatbot/
user_context.rs1use headless_lms_authorization::{Resource, fetch_user_roles};
2use headless_lms_models::chatbot_configurations::ChatbotConfiguration;
3use headless_lms_models::roles::Role;
4use tokio::sync::OnceCell;
5
6use crate::chatbot_error::ChatbotResult;
7use crate::chatbot_tools::tool_category::EnabledToolCategories;
8use crate::prelude::*;
9
10pub struct ChatbotTurnContext {
15 pub user_id: Option<Uuid>,
16 pub course_id: Option<Uuid>,
17 pub course_name: Option<String>,
18 pub conversation_id: Option<Uuid>,
21 pub enabled_tool_categories: EnabledToolCategories,
22 roles: OnceCell<Vec<Role>>,
23}
24
25impl ChatbotTurnContext {
26 pub fn new(
29 user_id: Option<Uuid>,
30 course_id: Option<Uuid>,
31 course_name: Option<String>,
32 conversation_id: Uuid,
33 configuration: &ChatbotConfiguration,
34 ) -> Self {
35 Self {
36 user_id,
37 course_id,
38 course_name,
39 conversation_id: Some(conversation_id),
40 enabled_tool_categories: EnabledToolCategories::from_configuration(configuration),
41 roles: OnceCell::new(),
42 }
43 }
44
45 pub fn turn_resource(&self) -> Resource {
48 match self.course_id {
49 Some(course_id) => Resource::Course(course_id),
50 None => Resource::GlobalPermissions,
51 }
52 }
53
54 pub(crate) async fn roles(&self, conn: &mut PgConnection) -> ChatbotResult<&[Role]> {
59 let roles = self
60 .roles
61 .get_or_try_init(|| async {
62 fetch_user_roles(conn, self.user_id)
63 .await
64 .map_err(ChatbotError::from)
65 })
66 .await?;
67 Ok(roles)
68 }
69
70 #[cfg(test)]
71 pub(crate) fn with_roles(
72 user_id: Option<Uuid>,
73 course_id: Option<Uuid>,
74 course_name: Option<String>,
75 roles: Vec<Role>,
76 ) -> Self {
77 Self::with_roles_and_categories(
78 user_id,
79 course_id,
80 course_name,
81 roles,
82 EnabledToolCategories::all(),
83 )
84 }
85
86 #[cfg(test)]
89 pub(crate) fn with_roles_and_categories(
90 user_id: Option<Uuid>,
91 course_id: Option<Uuid>,
92 course_name: Option<String>,
93 roles: Vec<Role>,
94 enabled_tool_categories: EnabledToolCategories,
95 ) -> Self {
96 Self {
97 user_id,
98 course_id,
99 course_name,
100 conversation_id: None,
101 enabled_tool_categories,
102 roles: OnceCell::new_with(Some(roles)),
103 }
104 }
105}