Refactor (#4)

Reviewed-on: #4
This commit is contained in:
2025-12-26 00:32:20 +00:00
parent 58de25e5bc
commit 1bacb454fa
11 changed files with 238 additions and 115 deletions

View File

@@ -18,6 +18,8 @@ mod auth;
mod config;
mod dto;
mod error;
#[cfg(feature = "smart-features")]
mod nats_broker;
mod routes;
mod state;
@@ -79,14 +81,7 @@ async fn main() -> anyhow::Result<()> {
.await
.map_err(|e| anyhow::anyhow!(e))?;
// Create services
use notes_domain::{NoteService, TagService, UserService};
let note_service = Arc::new(NoteService::new(note_repo.clone(), tag_repo.clone()));
let tag_service = Arc::new(TagService::new(tag_repo.clone()));
let user_service = Arc::new(UserService::new(user_repo.clone()));
// Connect to NATS
// Connect to NATS
// Connect to NATS (before creating services that depend on it)
#[cfg(feature = "smart-features")]
let nats_client = {
tracing::info!("Connecting to NATS: {}", config.broker_url);
@@ -95,6 +90,21 @@ async fn main() -> anyhow::Result<()> {
.map_err(|e| anyhow::anyhow!("NATS connection failed: {}", e))?
};
// Create services
use notes_domain::{NoteService, TagService, UserService};
// Build NoteService with optional MessageBroker
#[cfg(feature = "smart-features")]
let note_service = {
let broker = Arc::new(nats_broker::NatsMessageBroker::new(nats_client.clone()));
Arc::new(NoteService::new(note_repo.clone(), tag_repo.clone()).with_message_broker(broker))
};
#[cfg(not(feature = "smart-features"))]
let note_service = Arc::new(NoteService::new(note_repo.clone(), tag_repo.clone()));
let tag_service = Arc::new(TagService::new(tag_repo.clone()));
let user_service = Arc::new(UserService::new(user_repo.clone()));
// Create application state
let state = AppState::new(
note_repo,

View File

@@ -0,0 +1,31 @@
//! NATS message broker adapter for domain MessageBroker port
use async_trait::async_trait;
use notes_domain::{DomainError, DomainResult, MessageBroker, Note};
/// NATS adapter implementing the MessageBroker port
pub struct NatsMessageBroker {
client: async_nats::Client,
}
impl NatsMessageBroker {
pub fn new(client: async_nats::Client) -> Self {
Self { client }
}
}
#[async_trait]
impl MessageBroker for NatsMessageBroker {
async fn publish_note_updated(&self, note: &Note) -> DomainResult<()> {
let payload = serde_json::to_vec(note).map_err(|e| {
DomainError::RepositoryError(format!("Failed to serialize note: {}", e))
})?;
self.client
.publish("notes.updated", payload.into())
.await
.map_err(|e| DomainError::RepositoryError(format!("Failed to publish event: {}", e)))?;
Ok(())
}
}

View File

@@ -82,20 +82,7 @@ pub async fn create_note(
let note = state.note_service.create_note(domain_req).await?;
// Publish event
#[cfg(feature = "smart-features")]
{
let payload = serde_json::to_vec(&note).unwrap_or_default();
if let Err(e) = state
.nats_client
.publish("notes.updated", payload.into())
.await
{
tracing::error!("Failed to publish notes.updated event: {}", e);
} else {
tracing::info!("Published notes.updated event for note {}", note.id);
}
}
// Event publishing is now handled in NoteService via MessageBroker
Ok((StatusCode::CREATED, Json(NoteResponse::from(note))))
}
@@ -152,20 +139,7 @@ pub async fn update_note(
let note = state.note_service.update_note(domain_req).await?;
// Publish event
#[cfg(feature = "smart-features")]
{
let payload = serde_json::to_vec(&note).unwrap_or_default();
if let Err(e) = state
.nats_client
.publish("notes.updated", payload.into())
.await
{
tracing::error!("Failed to publish notes.updated event: {}", e);
} else {
tracing::info!("Published notes.updated event for note {}", note.id);
}
}
// Event publishing is now handled in NoteService via MessageBroker
Ok(Json(NoteResponse::from(note)))
}