gglib_core/ports/
chat_history.rs1use async_trait::async_trait;
7use thiserror::Error;
8
9use crate::domain::chat::{
10 Conversation, ConversationUpdate, Message, MessageRole, NewConversation, NewMessage,
11};
12
13#[derive(Debug, Error)]
15pub enum ChatHistoryError {
16 #[error("Conversation not found: {0}")]
17 ConversationNotFound(i64),
18
19 #[error("Message not found: {0}")]
20 MessageNotFound(i64),
21
22 #[error("Invalid message role: {0}")]
23 InvalidRole(String),
24
25 #[error("Database error: {0}")]
26 Database(String),
27}
28
29#[async_trait]
35pub trait ChatHistoryRepository: Send + Sync {
36 async fn create_conversation(&self, conv: NewConversation) -> Result<i64, ChatHistoryError>;
38
39 async fn list_conversations(&self) -> Result<Vec<Conversation>, ChatHistoryError>;
41
42 async fn get_conversation(&self, id: i64) -> Result<Option<Conversation>, ChatHistoryError>;
44
45 async fn update_conversation(
47 &self,
48 id: i64,
49 update: ConversationUpdate,
50 ) -> Result<(), ChatHistoryError>;
51
52 async fn delete_conversation(&self, id: i64) -> Result<(), ChatHistoryError>;
54
55 async fn get_conversation_count(&self) -> Result<i64, ChatHistoryError>;
57
58 async fn get_messages(&self, conversation_id: i64) -> Result<Vec<Message>, ChatHistoryError>;
60
61 async fn save_message(&self, msg: NewMessage) -> Result<i64, ChatHistoryError>;
63
64 async fn update_message(
66 &self,
67 id: i64,
68 content: String,
69 metadata: Option<serde_json::Value>,
70 ) -> Result<(), ChatHistoryError>;
71
72 async fn delete_message_and_subsequent(&self, id: i64) -> Result<i64, ChatHistoryError>;
75
76 async fn get_message_count(&self, conversation_id: i64) -> Result<i64, ChatHistoryError>;
78}
79
80pub fn validate_role(role: &str) -> Result<MessageRole, ChatHistoryError> {
82 MessageRole::parse(role).ok_or_else(|| ChatHistoryError::InvalidRole(role.to_string()))
83}