refactor!: CQRS repository split — v0.3.0
FederationRepository (34 methods) → 4 focused traits:
ActivityRepository (2) — idempotency tracking
FollowRepository (18) — follower/following graph + migration
ActorRepository (6) — keypairs, remote actor cache, announce tracking
BlocklistRepository (8) — domain + actor blocklists
ApObjectHandler (10 methods) → 2 traits:
ApContentReader (3) — get_local_objects_for_user/page, count_local_posts
ApObjectHandler (9) — all inbox callbacks (on_create, on_mention, etc.)
Builder changes from positional args to named setters:
ActivityPubService::builder(base_url)
.activity_repo(arc)
.follow_repo(arc)
.actor_repo(arc)
.blocklist_repo(arc)
.user_repo(arc)
.content_reader(arc)
.object_handler(arc)
.build()
No behaviour changes.
This commit is contained in:
@@ -46,7 +46,7 @@ impl Activity for AcceptActivity {
|
||||
}
|
||||
let local_user_id = crate::urls::extract_user_id_from_url(self.object.actor.inner())
|
||||
.ok_or_else(|| Error::bad_request(anyhow::anyhow!("invalid actor URL in Follow")))?;
|
||||
data.federation_repo
|
||||
data.follow_repo
|
||||
.update_following_status(
|
||||
local_user_id,
|
||||
self.actor.inner().as_str(),
|
||||
|
||||
@@ -57,7 +57,7 @@ impl Activity for AnnounceActivity {
|
||||
tracing::debug!(actor = %self.actor.inner(), object = %self.object, "received Announce of non-local object");
|
||||
return Ok(());
|
||||
}
|
||||
data.federation_repo
|
||||
data.actor_repo
|
||||
.add_announce(
|
||||
self.id.as_str(),
|
||||
self.object.as_str(),
|
||||
|
||||
@@ -45,8 +45,8 @@ impl Activity for BlockActivity {
|
||||
return Ok(());
|
||||
}
|
||||
if let Some(local_user_id) = crate::urls::extract_user_id_from_url(&self.object) {
|
||||
let _ = data.federation_repo.remove_following(local_user_id, self.actor.inner().as_str()).await;
|
||||
let _ = data.federation_repo.remove_follower(local_user_id, self.actor.inner().as_str()).await;
|
||||
let _ = data.follow_repo.remove_following(local_user_id, self.actor.inner().as_str()).await;
|
||||
let _ = data.follow_repo.remove_follower(local_user_id, self.actor.inner().as_str()).await;
|
||||
}
|
||||
tracing::info!(actor = %self.actor.inner(), "received block — removed following and follower");
|
||||
Ok(())
|
||||
|
||||
@@ -57,7 +57,7 @@ impl Activity for FollowActivity {
|
||||
}
|
||||
// Actor block checked BEFORE any outbound HTTP fetch.
|
||||
if let Some(target_user_id) = crate::urls::extract_user_id_from_url(self.object.inner()) {
|
||||
if data.federation_repo
|
||||
if data.blocklist_repo
|
||||
.is_actor_blocked(target_user_id, self.actor.inner().as_str())
|
||||
.await?
|
||||
{
|
||||
@@ -67,7 +67,7 @@ impl Activity for FollowActivity {
|
||||
}
|
||||
let _follower = self.actor.dereference(data).await?;
|
||||
let local_actor = self.object.dereference(data).await?;
|
||||
data.federation_repo
|
||||
data.follow_repo
|
||||
.add_follower(
|
||||
local_actor.user_id,
|
||||
self.actor.inner().as_str(),
|
||||
|
||||
@@ -9,13 +9,13 @@ use crate::error::Error;
|
||||
/// On repo error, skips the check rather than silently dropping the activity.
|
||||
pub(crate) async fn already_processed(activity_id: &Url, data: &Data<FederationData>) -> bool {
|
||||
let id = activity_id.as_str();
|
||||
match data.federation_repo.is_activity_processed(id).await {
|
||||
match data.activity_repo.is_activity_processed(id).await {
|
||||
Ok(true) => {
|
||||
tracing::debug!(activity_id = id, "duplicate activity, skipping");
|
||||
true
|
||||
}
|
||||
Ok(false) => {
|
||||
if let Err(e) = data.federation_repo.mark_activity_processed(id).await {
|
||||
if let Err(e) = data.activity_repo.mark_activity_processed(id).await {
|
||||
tracing::warn!(activity_id = id, error = %e, "failed to mark activity processed");
|
||||
}
|
||||
false
|
||||
@@ -39,7 +39,7 @@ pub(crate) async fn check_guards(
|
||||
return Ok(true);
|
||||
}
|
||||
let domain = actor.host_str().unwrap_or("");
|
||||
if data.federation_repo.is_domain_blocked(domain).await? {
|
||||
if data.blocklist_repo.is_domain_blocked(domain).await? {
|
||||
tracing::info!(actor = %actor, "ignoring activity from blocked domain");
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ impl Activity for MoveActivity {
|
||||
)));
|
||||
}
|
||||
let affected = data
|
||||
.federation_repo
|
||||
.follow_repo
|
||||
.migrate_follower_actor(self.object.as_str(), self.target.as_str())
|
||||
.await
|
||||
.map_err(|e| Error::from(anyhow::anyhow!("{e}")))?;
|
||||
|
||||
@@ -44,7 +44,7 @@ impl Activity for RejectActivity {
|
||||
return Ok(());
|
||||
}
|
||||
if let Some(user_id) = crate::urls::extract_user_id_from_url(self.object.actor.inner()) {
|
||||
data.federation_repo
|
||||
data.follow_repo
|
||||
.remove_following(user_id, self.actor.inner().as_str())
|
||||
.await?;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ impl Activity for UndoActivity {
|
||||
&& let Ok(url) = Url::parse(obj_url)
|
||||
&& let Some(user_id) = crate::urls::extract_user_id_from_url(&url)
|
||||
{
|
||||
data.federation_repo
|
||||
data.follow_repo
|
||||
.remove_follower(user_id, self.actor.inner().as_str())
|
||||
.await?;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user