Refactor handlers and OpenAPI documentation for improved readability and consistency
Some checks failed
lint / lint (push) Has been cancelled
test / unit (push) Has been cancelled
test / integration (push) Has been cancelled
lint / lint (pull_request) Failing after 6m49s
test / unit (pull_request) Successful in 16m24s
test / integration (pull_request) Failing after 17m7s

- Reorganized imports in health, notifications, social, thoughts, and users handlers for clarity.
- Updated function signatures in handlers to improve readability by aligning parameters.
- Enhanced JSON response formatting in notifications and thoughts handlers.
- Improved error handling in user-related functions.
- Refactored OpenAPI documentation to maintain consistent formatting and structure.
- Cleaned up unnecessary code and comments across various files.
- Ensured consistent use of `Arc` for shared state in AppState and WorkerHandlers.
This commit is contained in:
2026-05-14 16:28:57 +02:00
parent 004bfb427b
commit 10c4a66de5
47 changed files with 2406 additions and 723 deletions

View File

@@ -1,4 +1,3 @@
use std::sync::Arc;
use chrono::Utc;
use domain::{
errors::DomainError,
@@ -7,9 +6,10 @@ use domain::{
ports::{NotificationRepository, ThoughtRepository},
value_objects::{NotificationId, UserId},
};
use std::sync::Arc;
pub struct NotificationEventService {
pub thoughts: Arc<dyn ThoughtRepository>,
pub thoughts: Arc<dyn ThoughtRepository>,
pub notifications: Arc<dyn NotificationRepository>,
}
@@ -20,50 +20,75 @@ fn is_self_action(thought_author: &UserId, actor: &UserId) -> bool {
impl NotificationEventService {
pub async fn process(&self, event: &DomainEvent) -> Result<(), DomainError> {
match event {
DomainEvent::LikeAdded { like_id: _, user_id, thought_id } => {
DomainEvent::LikeAdded {
like_id: _,
user_id,
thought_id,
} => {
let thought = match self.thoughts.find_by_id(thought_id).await? {
Some(t) => t,
None => return Ok(()),
};
if is_self_action(&thought.user_id, user_id) { return Ok(()); }
self.notifications.save(&Notification {
id: NotificationId::new(),
user_id: thought.user_id,
notification_type: NotificationType::Like,
from_user_id: Some(user_id.clone()),
thought_id: Some(thought_id.clone()),
read: false,
created_at: Utc::now(),
}).await
if is_self_action(&thought.user_id, user_id) {
return Ok(());
}
self.notifications
.save(&Notification {
id: NotificationId::new(),
user_id: thought.user_id,
notification_type: NotificationType::Like,
from_user_id: Some(user_id.clone()),
thought_id: Some(thought_id.clone()),
read: false,
created_at: Utc::now(),
})
.await
}
DomainEvent::BoostAdded { boost_id: _, user_id, thought_id } => {
DomainEvent::BoostAdded {
boost_id: _,
user_id,
thought_id,
} => {
let thought = match self.thoughts.find_by_id(thought_id).await? {
Some(t) => t,
None => return Ok(()),
};
if is_self_action(&thought.user_id, user_id) { return Ok(()); }
self.notifications.save(&Notification {
id: NotificationId::new(),
user_id: thought.user_id,
notification_type: NotificationType::Boost,
from_user_id: Some(user_id.clone()),
thought_id: Some(thought_id.clone()),
read: false,
created_at: Utc::now(),
}).await
if is_self_action(&thought.user_id, user_id) {
return Ok(());
}
self.notifications
.save(&Notification {
id: NotificationId::new(),
user_id: thought.user_id,
notification_type: NotificationType::Boost,
from_user_id: Some(user_id.clone()),
thought_id: Some(thought_id.clone()),
read: false,
created_at: Utc::now(),
})
.await
}
DomainEvent::FollowAccepted { follower_id, following_id } => {
self.notifications.save(&Notification {
id: NotificationId::new(),
user_id: following_id.clone(),
notification_type: NotificationType::Follow,
from_user_id: Some(follower_id.clone()),
thought_id: None,
read: false,
created_at: Utc::now(),
}).await
DomainEvent::FollowAccepted {
follower_id,
following_id,
} => {
self.notifications
.save(&Notification {
id: NotificationId::new(),
user_id: following_id.clone(),
notification_type: NotificationType::Follow,
from_user_id: Some(follower_id.clone()),
thought_id: None,
read: false,
created_at: Utc::now(),
})
.await
}
DomainEvent::ThoughtCreated { thought_id, user_id, in_reply_to_id } => {
DomainEvent::ThoughtCreated {
thought_id,
user_id,
in_reply_to_id,
} => {
let reply_to_id = match in_reply_to_id {
Some(id) => id,
None => return Ok(()),
@@ -72,16 +97,20 @@ impl NotificationEventService {
Some(t) => t,
None => return Ok(()),
};
if is_self_action(&original.user_id, user_id) { return Ok(()); }
self.notifications.save(&Notification {
id: NotificationId::new(),
user_id: original.user_id,
notification_type: NotificationType::Reply,
from_user_id: Some(user_id.clone()),
thought_id: Some(thought_id.clone()),
read: false,
created_at: Utc::now(),
}).await
if is_self_action(&original.user_id, user_id) {
return Ok(());
}
self.notifications
.save(&Notification {
id: NotificationId::new(),
user_id: original.user_id,
notification_type: NotificationType::Reply,
from_user_id: Some(user_id.clone()),
thought_id: Some(thought_id.clone()),
read: false,
created_at: Utc::now(),
})
.await
}
_ => Ok(()),
}
@@ -92,7 +121,10 @@ impl NotificationEventService {
mod tests {
use super::*;
use domain::{
models::{thought::{Thought, Visibility}, user::User},
models::{
thought::{Thought, Visibility},
user::User,
},
testing::TestStore,
value_objects::*,
};
@@ -113,9 +145,13 @@ mod tests {
let alice = alice();
let bob_id = UserId::new();
let thought = Thought::new_local(
ThoughtId::new(), alice.id.clone(),
ThoughtId::new(),
alice.id.clone(),
Content::new_local("hello").unwrap(),
None, Visibility::Public, None, false,
None,
Visibility::Public,
None,
false,
);
store.thoughts.lock().unwrap().push(thought.clone());
let svc = NotificationEventService {
@@ -126,10 +162,15 @@ mod tests {
like_id: LikeId::new(),
user_id: bob_id,
thought_id: thought.id.clone(),
}).await.unwrap();
})
.await
.unwrap();
let notifs = store.notifications.lock().unwrap();
assert_eq!(notifs.len(), 1);
assert!(matches!(notifs[0].notification_type, NotificationType::Like));
assert!(matches!(
notifs[0].notification_type,
NotificationType::Like
));
}
#[tokio::test]
@@ -137,9 +178,13 @@ mod tests {
let store = TestStore::default();
let alice = alice();
let thought = Thought::new_local(
ThoughtId::new(), alice.id.clone(),
ThoughtId::new(),
alice.id.clone(),
Content::new_local("hello").unwrap(),
None, Visibility::Public, None, false,
None,
Visibility::Public,
None,
false,
);
store.thoughts.lock().unwrap().push(thought.clone());
let svc = NotificationEventService {
@@ -150,7 +195,9 @@ mod tests {
like_id: LikeId::new(),
user_id: alice.id.clone(),
thought_id: thought.id.clone(),
}).await.unwrap();
})
.await
.unwrap();
assert!(store.notifications.lock().unwrap().is_empty());
}
@@ -166,10 +213,15 @@ mod tests {
svc.process(&DomainEvent::FollowAccepted {
follower_id: bob_id,
following_id: alice.id.clone(),
}).await.unwrap();
})
.await
.unwrap();
let notifs = store.notifications.lock().unwrap();
assert_eq!(notifs.len(), 1);
assert!(matches!(notifs[0].notification_type, NotificationType::Follow));
assert!(matches!(
notifs[0].notification_type,
NotificationType::Follow
));
}
#[tokio::test]
@@ -178,9 +230,13 @@ mod tests {
let alice = alice();
let bob_id = UserId::new();
let original = Thought::new_local(
ThoughtId::new(), alice.id.clone(),
ThoughtId::new(),
alice.id.clone(),
Content::new_local("original").unwrap(),
None, Visibility::Public, None, false,
None,
Visibility::Public,
None,
false,
);
store.thoughts.lock().unwrap().push(original.clone());
let svc = NotificationEventService {
@@ -191,10 +247,15 @@ mod tests {
thought_id: ThoughtId::new(),
user_id: bob_id,
in_reply_to_id: Some(original.id.clone()),
}).await.unwrap();
})
.await
.unwrap();
let notifs = store.notifications.lock().unwrap();
assert_eq!(notifs.len(), 1);
assert!(matches!(notifs[0].notification_type, NotificationType::Reply));
assert!(matches!(
notifs[0].notification_type,
NotificationType::Reply
));
}
#[tokio::test]
@@ -202,9 +263,13 @@ mod tests {
let store = TestStore::default();
let alice = alice();
let original = Thought::new_local(
ThoughtId::new(), alice.id.clone(),
ThoughtId::new(),
alice.id.clone(),
Content::new_local("original").unwrap(),
None, Visibility::Public, None, false,
None,
Visibility::Public,
None,
false,
);
store.thoughts.lock().unwrap().push(original.clone());
let svc = NotificationEventService {
@@ -215,7 +280,9 @@ mod tests {
thought_id: ThoughtId::new(),
user_id: alice.id.clone(),
in_reply_to_id: Some(original.id.clone()),
}).await.unwrap();
})
.await
.unwrap();
assert!(store.notifications.lock().unwrap().is_empty());
}
@@ -224,9 +291,13 @@ mod tests {
let store = TestStore::default();
let alice = alice();
let thought = Thought::new_local(
ThoughtId::new(), alice.id.clone(),
ThoughtId::new(),
alice.id.clone(),
Content::new_local("hello").unwrap(),
None, Visibility::Public, None, false,
None,
Visibility::Public,
None,
false,
);
store.thoughts.lock().unwrap().push(thought.clone());
let svc = NotificationEventService {
@@ -237,7 +308,9 @@ mod tests {
boost_id: BoostId::new(),
user_id: alice.id.clone(),
thought_id: thought.id.clone(),
}).await.unwrap();
})
.await
.unwrap();
assert!(store.notifications.lock().unwrap().is_empty());
}
}