refactor(domain): algebraic NotificationKind — invalid states now unrepresentable

This commit is contained in:
2026-05-15 13:53:53 +02:00
parent 189901b778
commit 5a64dd361c
4 changed files with 170 additions and 98 deletions

View File

@@ -2,9 +2,9 @@ use chrono::Utc;
use domain::{
errors::DomainError,
events::DomainEvent,
models::notification::{Notification, NotificationType},
models::notification::{Notification, NotificationKind},
ports::{NotificationRepository, ThoughtRepository},
value_objects::{NotificationId, UserId},
value_objects::NotificationId,
};
use std::sync::Arc;
@@ -13,7 +13,10 @@ pub struct NotificationEventService {
pub notifications: Arc<dyn NotificationRepository>,
}
fn is_self_action(thought_author: &UserId, actor: &UserId) -> bool {
fn is_self_action(
thought_author: &domain::value_objects::UserId,
actor: &domain::value_objects::UserId,
) -> bool {
thought_author == actor
}
@@ -36,9 +39,10 @@ impl NotificationEventService {
.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()),
kind: NotificationKind::Like {
thought_id: thought_id.clone(),
from_user_id: user_id.clone(),
},
read: false,
created_at: Utc::now(),
})
@@ -60,9 +64,10 @@ impl NotificationEventService {
.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()),
kind: NotificationKind::Boost {
thought_id: thought_id.clone(),
from_user_id: user_id.clone(),
},
read: false,
created_at: Utc::now(),
})
@@ -76,9 +81,9 @@ impl NotificationEventService {
.save(&Notification {
id: NotificationId::new(),
user_id: following_id.clone(),
notification_type: NotificationType::Follow,
from_user_id: Some(follower_id.clone()),
thought_id: None,
kind: NotificationKind::Follow {
from_user_id: follower_id.clone(),
},
read: false,
created_at: Utc::now(),
})
@@ -104,9 +109,10 @@ impl NotificationEventService {
.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()),
kind: NotificationKind::Reply {
thought_id: thought_id.clone(),
from_user_id: user_id.clone(),
},
read: false,
created_at: Utc::now(),
})
@@ -121,9 +127,10 @@ impl NotificationEventService {
.save(&Notification {
id: NotificationId::new(),
user_id: mentioned_user_id.clone(),
notification_type: NotificationType::Mention,
from_user_id: Some(author_user_id.clone()),
thought_id: Some(thought_id.clone()),
kind: NotificationKind::Mention {
thought_id: thought_id.clone(),
from_user_id: author_user_id.clone(),
},
read: false,
created_at: Utc::now(),
})
@@ -139,6 +146,7 @@ mod tests {
use super::*;
use domain::{
models::{
notification::NotificationKind,
thought::{Thought, Visibility},
user::User,
},
@@ -184,10 +192,7 @@ mod tests {
.unwrap();
let notifs = store.notifications.lock().unwrap();
assert_eq!(notifs.len(), 1);
assert!(matches!(
notifs[0].notification_type,
NotificationType::Like
));
assert!(matches!(notifs[0].kind, NotificationKind::Like { .. }));
}
#[tokio::test]
@@ -235,10 +240,7 @@ mod tests {
.unwrap();
let notifs = store.notifications.lock().unwrap();
assert_eq!(notifs.len(), 1);
assert!(matches!(
notifs[0].notification_type,
NotificationType::Follow
));
assert!(matches!(notifs[0].kind, NotificationKind::Follow { .. }));
}
#[tokio::test]
@@ -269,10 +271,7 @@ mod tests {
.unwrap();
let notifs = store.notifications.lock().unwrap();
assert_eq!(notifs.len(), 1);
assert!(matches!(
notifs[0].notification_type,
NotificationType::Reply
));
assert!(matches!(notifs[0].kind, NotificationKind::Reply { .. }));
}
#[tokio::test]