use crate::command::context::CommandContext; use crate::command::handler::{CommandHandler, CommandMetadata}; use crate::command::response::{CommandError, CommandResponse, MessageKind}; use crate::command::Command; use crate::protocol::SessionSummary; use crate::storage::SessionStore; use async_trait::async_trait; use std::sync::Arc; /// 按通道列出会话命令处理器 pub struct ListSessionsByChannelCommandHandler { store: Arc, } impl ListSessionsByChannelCommandHandler { pub fn new(store: Arc) -> Self { Self { store } } } #[async_trait] impl CommandHandler for ListSessionsByChannelCommandHandler { fn can_handle(&self, cmd: &Command) -> bool { matches!(cmd, Command::ListSessionsByChannel { .. }) } fn metadata(&self) -> Option { Some(CommandMetadata { name: "list_by_channel", description: "列出指定通道的所有会话", usage: "/list_by_channel ", }) } async fn handle( &self, cmd: Command, ctx: CommandContext, ) -> Result { match cmd { Command::ListSessionsByChannel { channel_name, include_archived, } => handle_list_sessions_by_channel(self, channel_name, include_archived, ctx).await, _ => unreachable!(), } } } async fn handle_list_sessions_by_channel( handler: &ListSessionsByChannelCommandHandler, channel_name: String, include_archived: bool, ctx: CommandContext, ) -> Result { let sessions = handler .store .list_sessions(&channel_name, include_archived) .map_err(|e| CommandError::new("LIST_SESSIONS_ERROR", e.to_string()))?; let summaries: Vec = sessions .into_iter() .map(|s| SessionSummary { session_id: s.id, title: s.title, channel_name: s.channel_name, chat_id: s.chat_id, message_count: s.message_count, last_active_at: s.last_active_at, archived_at: s.archived_at, }) .collect(); let sessions_json = serde_json::to_string(&summaries) .map_err(|e| CommandError::new("SERIALIZE_ERROR", e.to_string()))?; let message = format!( "Found {} session(s) in channel '{}'", summaries.len(), channel_name ); Ok(CommandResponse::success(ctx.request_id) .with_message(MessageKind::Notification, &message) .with_metadata("sessions", &sessions_json) .with_metadata("channel_name", &channel_name) .with_metadata("count", &summaries.len().to_string())) }