headless_lms_models/
chatbot_conversations.rs1use futures::future::OptionFuture;
2
3use crate::{
4 chatbot_conversation_messages::ChatbotConversationMessage,
5 chatbot_conversation_messages_citations::ChatbotConversationMessageCitation, prelude::*,
6};
7
8#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
9#[cfg_attr(feature = "ts_rs", derive(TS))]
10pub struct ChatbotConversation {
11 pub id: Uuid,
12 pub created_at: DateTime<Utc>,
13 pub updated_at: DateTime<Utc>,
14 pub deleted_at: Option<DateTime<Utc>>,
15 pub course_id: Uuid,
16 pub user_id: Uuid,
17 pub chatbot_configuration_id: Uuid,
18}
19
20#[derive(Serialize, Deserialize, PartialEq, Clone)]
21#[cfg_attr(feature = "ts_rs", derive(TS))]
22pub struct ChatbotConversationInfo {
24 pub current_conversation: Option<ChatbotConversation>,
25 pub current_conversation_messages: Option<Vec<ChatbotConversationMessage>>,
26 pub current_conversation_message_citations: Option<Vec<ChatbotConversationMessageCitation>>,
27 pub chatbot_name: String,
28 pub hide_citations: bool,
29}
30
31pub async fn insert(
32 conn: &mut PgConnection,
33 input: ChatbotConversation,
34) -> ModelResult<ChatbotConversation> {
35 let res = sqlx::query_as!(
36 ChatbotConversation,
37 r#"
38INSERT INTO chatbot_conversations (course_id, user_id, chatbot_configuration_id)
39VALUES ($1, $2, $3)
40RETURNING *
41 "#,
42 input.course_id,
43 input.user_id,
44 input.chatbot_configuration_id
45 )
46 .fetch_one(conn)
47 .await?;
48 Ok(res)
49}
50
51pub async fn get_latest_conversation_for_user(
52 conn: &mut PgConnection,
53 user_id: Uuid,
54 chatbot_configuration_id: Uuid,
55) -> ModelResult<ChatbotConversation> {
56 let res = sqlx::query_as!(
57 ChatbotConversation,
58 r#"
59SELECT *
60FROM chatbot_conversations
61WHERE user_id = $1
62 AND chatbot_configuration_id = $2
63 AND deleted_at IS NULL
64ORDER BY created_at DESC
65LIMIT 1
66 "#,
67 user_id,
68 chatbot_configuration_id
69 )
70 .fetch_one(conn)
71 .await?;
72 Ok(res)
73}
74
75pub async fn get_current_conversation_info(
77 tx: &mut PgConnection,
78 user_id: Uuid,
79 chatbot_configuration_id: Uuid,
80) -> ModelResult<ChatbotConversationInfo> {
81 let chatbot_configuration =
82 crate::chatbot_configurations::get_by_id(tx, chatbot_configuration_id).await?;
83 let current_conversation =
84 get_latest_conversation_for_user(tx, user_id, chatbot_configuration_id)
85 .await
86 .optional()?;
87 let current_conversation_messages = OptionFuture::from(
88 current_conversation
89 .clone()
90 .map(|c| crate::chatbot_conversation_messages::get_by_conversation_id(tx, c.id)),
91 )
92 .await
93 .transpose()?;
94
95 let current_conversation_message_citations =
96 OptionFuture::from(current_conversation.clone().map(|c| {
97 crate::chatbot_conversation_messages_citations::get_by_conversation_id(tx, c.id)
98 }))
99 .await
100 .transpose()?;
101
102 Ok(ChatbotConversationInfo {
103 current_conversation,
104 current_conversation_messages,
105 current_conversation_message_citations,
106 chatbot_name: chatbot_configuration.chatbot_name,
108 hide_citations: chatbot_configuration.hide_citations,
109 })
110}