use crate::error::RoomError; use crate::service::RoomService; use crate::ws_context::WsUserContext; use chrono::Utc; use models::rooms::{room_message, room_thread}; use sea_orm::*; use uuid::Uuid; impl RoomService { pub async fn room_thread_list( &self, room_id: Uuid, ctx: &WsUserContext, ) -> Result, RoomError> { let user_id = ctx.user_id; self.require_room_member(room_id, user_id).await?; let models = room_thread::Entity::find() .filter(room_thread::Column::Room.eq(room_id)) .order_by_desc(room_thread::Column::LastMessageAt) .all(&self.db) .await?; Ok(models .into_iter() .map(super::RoomThreadResponse::from) .collect()) } pub async fn room_thread_create( &self, room_id: Uuid, request: super::RoomThreadCreateRequest, ctx: &WsUserContext, ) -> Result { let user_id = ctx.user_id; self.require_room_member(room_id, user_id).await?; let parent = room_message::Entity::find() .filter(room_message::Column::Room.eq(room_id)) .filter(room_message::Column::Seq.eq(request.parent_seq)) .one(&self.db) .await?; if parent.is_none() { return Err(RoomError::NotFound("Parent message not found".to_string())); } let now = Utc::now(); let participants = serde_json::json!([user_id]); let model = room_thread::ActiveModel { id: Set(Uuid::now_v7()), room: Set(room_id), parent: Set(request.parent_seq), created_by: Set(user_id), participants: Set(participants), last_message_at: Set(now), last_message_preview: Set(None), created_at: Set(now), updated_at: Set(now), } .insert(&self.db) .await?; Ok(super::RoomThreadResponse::from(model)) } pub async fn room_thread_messages( &self, thread_id: Uuid, before_seq: Option, after_seq: Option, limit: Option, ctx: &WsUserContext, ) -> Result { let user_id = ctx.user_id; let thread = room_thread::Entity::find_by_id(thread_id) .one(&self.db) .await? .ok_or_else(|| RoomError::NotFound("Thread not found".to_string()))?; self.require_room_member(thread.room, user_id).await?; let mut query = room_message::Entity::find().filter(room_message::Column::Thread.eq(Some(thread.id))); if let Some(before_seq) = before_seq { query = query.filter(room_message::Column::Seq.lt(before_seq)); } if let Some(after_seq) = after_seq { query = query.filter(room_message::Column::Seq.gt(after_seq)); } let total = query.clone().count(&self.db).await? as i64; let models = query .order_by_desc(room_message::Column::Seq) .limit(limit.unwrap_or(50)) .all(&self.db) .await?; let mut messages: Vec = models .into_iter() .map(super::RoomMessageResponse::from) .collect(); messages.reverse(); Ok(super::RoomMessageListResponse { messages, total }) } }