feat: v2 rewrite — hexagonal arch, ActivityPub federation, NATS, deployment-ready #1

Merged
GKaszewski merged 334 commits from v2 into master 2026-05-16 09:42:43 +00:00
Showing only changes of commit 2754e3e820 - Show all commits

View File

@@ -8,7 +8,6 @@ use domain::{
ports::{EngagementRepository, EventPublisher, OutboxWriter, TagRepository, ThoughtRepository, UserReader},
value_objects::{Content, ThoughtId, UserId},
};
use std::collections::HashMap;
fn require_owner(thought: &Thought, user_id: &UserId) -> Result<(), DomainError> {
if thought.user_id != *user_id {
@@ -117,20 +116,6 @@ pub async fn edit_thought(
Ok(())
}
pub async fn get_thought(
thoughts: &dyn ThoughtRepository,
id: &ThoughtId,
) -> Result<Thought, DomainError> {
thoughts.find_by_id(id).await?.ok_or(DomainError::NotFound)
}
pub async fn get_thread(
thoughts: &dyn ThoughtRepository,
id: &ThoughtId,
) -> Result<Vec<Thought>, DomainError> {
thoughts.get_thread(id).await
}
/// Fetches a single thought enriched with author + real engagement stats.
pub async fn get_thought_view(
thoughts: &dyn ThoughtRepository,
@@ -148,9 +133,9 @@ pub async fn get_thought_view(
.await?
.ok_or(DomainError::NotFound)?;
let mut map = engagement.get_for_thoughts(&[id.clone()], viewer).await?;
let (stats, viewer_ctx) = map.remove(id).unwrap_or_else(|| {
let (stats, viewer_ctx) = map.remove(id).unwrap_or(
(EngagementStats { like_count: 0, boost_count: 0, reply_count: 0 }, None)
});
);
Ok(FeedEntry { thought, author, stats, viewer: viewer_ctx })
}
@@ -184,9 +169,9 @@ pub async fn get_thread_views(
.get(&thought.user_id)
.cloned()
.ok_or(DomainError::NotFound)?;
let (stats, viewer_ctx) = engagement_map.remove(&thought.id).unwrap_or_else(|| {
let (stats, viewer_ctx) = engagement_map.remove(&thought.id).unwrap_or(
(EngagementStats { like_count: 0, boost_count: 0, reply_count: 0 }, None)
});
);
entries.push(FeedEntry { thought, author, stats, viewer: viewer_ctx });
}
Ok(entries)