#1 count_accepted_followers / get_accepted_followers_page: new DB-side methods on FollowRepository — no more loading all followers into memory to count or page them. #2 Move re-follows are now non-blocking: tokio::spawn instead of awaiting each sign_and_send inside receive() — inbox handler no longer stalls for slow remote servers during account migration. #3 Remove get_local_objects_for_user from ApContentReader (dead code). Backfill and outbox both use the paginated get_local_objects_page. #6 Rename backfill_outbox → import_remote_outbox with a clear doc explaining the direction (import FROM a remote server, not to a follower). #7 also_known_as: Option<String> → Vec<String> on ApUser, LookedUpActor, and DbActor. from_json now stores all aliases; move_act.rs checks all. Mentions: broadcast_create_note / broadcast_update_note now accept mentioned_inboxes: Vec<Url> — delivery goes to followers + mentioned actors who aren't already followers. Deduplication is done before sending. Pass vec![] if note has no external mentions. Docs: ApObjectHandler and ApContentReader now have complete doc comments with contracts, idempotency guidance, and error-handling semantics.
99 lines
3.9 KiB
Rust
99 lines
3.9 KiB
Rust
use anyhow::Result;
|
|
use async_trait::async_trait;
|
|
|
|
use super::{Follower, FollowerStatus, FollowingStatus, RemoteActor};
|
|
|
|
/// Manages follower/following relationships and account migration.
|
|
#[async_trait]
|
|
pub trait FollowRepository: Send + Sync {
|
|
// ── Inbound followers ───────────────────────────────────────────────────
|
|
async fn add_follower(
|
|
&self,
|
|
local_user_id: uuid::Uuid,
|
|
remote_actor_url: &str,
|
|
status: FollowerStatus,
|
|
follow_activity_id: &str,
|
|
) -> Result<()>;
|
|
async fn get_follower_follow_activity_id(
|
|
&self,
|
|
local_user_id: uuid::Uuid,
|
|
remote_actor_url: &str,
|
|
) -> Result<Option<String>>;
|
|
async fn remove_follower(
|
|
&self,
|
|
local_user_id: uuid::Uuid,
|
|
remote_actor_url: &str,
|
|
) -> Result<()>;
|
|
async fn get_followers(&self, local_user_id: uuid::Uuid) -> Result<Vec<Follower>>;
|
|
async fn get_followers_page(
|
|
&self,
|
|
local_user_id: uuid::Uuid,
|
|
offset: u32,
|
|
limit: usize,
|
|
) -> Result<Vec<Follower>>;
|
|
async fn count_followers(&self, local_user_id: uuid::Uuid) -> Result<usize>;
|
|
async fn update_follower_status(
|
|
&self,
|
|
local_user_id: uuid::Uuid,
|
|
remote_actor_url: &str,
|
|
status: FollowerStatus,
|
|
) -> Result<()>;
|
|
async fn get_pending_followers(&self, local_user_id: uuid::Uuid) -> Result<Vec<RemoteActor>>;
|
|
/// Return deduplicated inbox URLs (shared_inbox preferred) for accepted
|
|
/// followers, excluding blocked actors/domains. DB-side filtering.
|
|
async fn get_accepted_follower_inboxes(&self, local_user_id: uuid::Uuid)
|
|
-> Result<Vec<String>>;
|
|
/// Count of accepted followers only. More efficient than loading all followers
|
|
/// and filtering in application memory.
|
|
async fn count_accepted_followers(&self, local_user_id: uuid::Uuid) -> Result<usize>;
|
|
/// Accepted followers page for display purposes. `offset` is 0-based.
|
|
async fn get_accepted_followers_page(
|
|
&self,
|
|
local_user_id: uuid::Uuid,
|
|
offset: u32,
|
|
limit: usize,
|
|
) -> Result<Vec<RemoteActor>>;
|
|
|
|
// ── Outbound following ──────────────────────────────────────────────────
|
|
async fn add_following(
|
|
&self,
|
|
local_user_id: uuid::Uuid,
|
|
actor: RemoteActor,
|
|
follow_activity_id: &str,
|
|
) -> Result<()>;
|
|
async fn get_follow_activity_id(
|
|
&self,
|
|
local_user_id: uuid::Uuid,
|
|
remote_actor_url: &str,
|
|
) -> Result<Option<String>>;
|
|
async fn remove_following(&self, local_user_id: uuid::Uuid, actor_url: &str) -> Result<()>;
|
|
async fn get_following(&self, local_user_id: uuid::Uuid) -> Result<Vec<RemoteActor>>;
|
|
async fn get_following_page(
|
|
&self,
|
|
local_user_id: uuid::Uuid,
|
|
offset: u32,
|
|
limit: usize,
|
|
) -> Result<Vec<RemoteActor>>;
|
|
async fn count_following(&self, local_user_id: uuid::Uuid) -> Result<usize>;
|
|
async fn update_following_status(
|
|
&self,
|
|
local_user_id: uuid::Uuid,
|
|
remote_actor_url: &str,
|
|
status: FollowingStatus,
|
|
) -> Result<()>;
|
|
async fn get_following_outbox_url(
|
|
&self,
|
|
local_user_id: uuid::Uuid,
|
|
remote_actor_url: &str,
|
|
) -> Result<Option<String>>;
|
|
|
|
// ── Account migration ───────────────────────────────────────────────────
|
|
/// Migrate all follower records from `old_actor_url` to `new_actor_url`.
|
|
/// Returns local user IDs that need a re-follow sent.
|
|
async fn migrate_follower_actor(
|
|
&self,
|
|
old_actor_url: &str,
|
|
new_actor_url: &str,
|
|
) -> Result<Vec<uuid::Uuid>>;
|
|
}
|