Files
zesdex/apps/application/src/cms/conversation_service.rs
T
asepharyana da2ed6da25 feat(tui): add usage overlay and sidebar for displaying usage statistics and tasks
feat(tui): implement status bar with connection and turn state indicators
feat(tui): create workflow panel for agent status and progress visualization
feat(web): introduce web frontend interface with static file serving
feat(ws): add WebSocket interface for real-time communication and session management
2026-07-20 09:04:57 +07:00

73 lines
2.4 KiB
Rust

//! Conversation use-case implementation.
//!
//! `ConversationServiceImpl` implements [`ConversationService`] from the
//! domain layer. It is generic over `R: ConversationRepository`, delegating
//! all persistence to that adapter.
//!
//! # Flow
//!
//! Each method computes the session directory from the session ID, then
//! delegates the actual I/O to the injected `repo`. Error context is
//! added at this layer to identify which session caused the failure.
use std::path::PathBuf;
use tracing;
use zesdex_domain::cms::{Conversation, ConversationRepository, ServiceError};
use zesdex_domain::core::ChatMessage;
/// Service implementation for conversation CRUD operations.
///
/// Generic over `R: ConversationRepository` so the persistence layer
/// can be swapped without changing business logic.
pub struct ConversationServiceImpl<R> {
pub repo: R,
/// Base directory containing session subdirectories.
pub sessions_dir: PathBuf,
}
impl<R: ConversationRepository> ConversationServiceImpl<R> {
/// Create a new service with the given repository and sessions directory.
pub fn new(repo: R, sessions_dir: impl Into<PathBuf>) -> Self {
tracing::debug!("creating ConversationServiceImpl");
Self {
repo,
sessions_dir: sessions_dir.into(),
}
}
/// Compute the session directory for a given session id.
fn session_dir(&self, session_id: &str) -> PathBuf {
self.sessions_dir.join(session_id)
}
}
impl<R: ConversationRepository> zesdex_domain::cms::ConversationService
for ConversationServiceImpl<R>
{
fn load_conversation(&self, session_id: &str) -> Result<Conversation, ServiceError> {
tracing::debug!("loading conversation for session {session_id}");
let dir = self.session_dir(session_id);
self.repo.load(&dir).map_err(ServiceError::Repository)
}
fn save_conversation(&self, conv: &Conversation) -> Result<(), ServiceError> {
tracing::debug!("saving conversation for session {}", conv.session_id);
let dir = self.session_dir(&conv.session_id);
self.repo.save(&dir, conv)?;
Ok(())
}
fn add_message(
&self,
conv: &mut Conversation,
msg: ChatMessage,
) -> Result<(), ServiceError> {
tracing::debug!("adding message to session {}", conv.session_id);
conv.push(msg);
let dir = self.session_dir(&conv.session_id);
self.repo.save(&dir, conv)?;
Ok(())
}
}