use models::ai::{AiSharedConversation, ai_conversation, ai_shared_conversation}; use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set}; use crate::error::AppError; use uuid::Uuid; use crate::AppService; impl AppService { pub async fn share_conversation( &self, conversation_id: Uuid, user_id: Uuid, ) -> Result<(ai_shared_conversation::Model, String), AppError> { let c = self.find_conversation_owned(conversation_id, user_id).await?; let share_token = Uuid::new_v4().to_string().replace("-", ""); let now = chrono::Utc::now(); let share = ai_shared_conversation::ActiveModel { id: Set(Uuid::new_v4()), conversation_id: Set(conversation_id), share_token: Set(share_token.clone()), created_by: Set(user_id), view_count: Set(0), created_at: Set(now), expires_at: Set(None), } .insert(self.db.writer()) .await?; let mut updated: ai_conversation::ActiveModel = c.into(); updated.is_shared = Set(true); updated.update(self.db.writer()).await?; Ok((share, share_token)) } pub async fn get_shared_conversation( &self, conversation_id: Uuid, share_token: String, ) -> Result { let share = AiSharedConversation::find() .filter(ai_shared_conversation::Column::ShareToken.eq(&share_token)) .one(self.db.reader()) .await? .ok_or_else(|| AppError::NotFound("shared conversation".into()))?; if share.conversation_id != conversation_id { return Err(AppError::NotFound("shared conversation".into())); } if let Some(expires_at) = share.expires_at { if expires_at < chrono::Utc::now() { return Err(AppError::NotFound("share link expired".into())); } } let c = self.find_conversation(conversation_id).await?; // Increment view count let view_count = share.view_count; let mut share_active: ai_shared_conversation::ActiveModel = share.into(); share_active.view_count = Set(view_count + 1); let _ = share_active.update(self.db.writer()).await; Ok(c) } }