refactor: remove SocialQueryPort — replaced by SocialQuery + FederationAdminQuery

-319 lines. Legacy SocialQueryPort trait, NoopSocialQueryPort,
PanicSocialQueryPort all deleted. Federation repos now implement
FederationAdminQuery (single method). get_users uses FederationAdminQuery.
All other consumers use unified SocialQuery.
This commit is contained in:
2026-07-10 16:02:27 +02:00
parent 7cfa234902
commit 44d7df33a2
19 changed files with 32 additions and 319 deletions

View File

@@ -1,26 +1,14 @@
use async_trait::async_trait;
use domain::{
errors::DomainError,
models::{PendingFollowerInfo, RemoteActorInfo},
ports::SocialQueryPort,
value_objects::UserId,
models::RemoteActorInfo,
ports::FederationAdminQuery,
};
use super::SqliteFederationRepository;
#[async_trait]
impl SocialQueryPort for SqliteFederationRepository {
async fn get_accepted_following_urls(
&self,
user_id: &UserId,
) -> Result<Vec<String>, DomainError> {
let user_id_str = user_id.value().to_string();
sqlx::query_scalar::<_, String>(
"SELECT remote_actor_url FROM ap_following WHERE local_user_id = ? AND status = 'accepted'",
).bind(&user_id_str).fetch_all(&self.pool).await
.map_err(|e| DomainError::InfrastructureError(e.to_string()))
}
impl FederationAdminQuery for SqliteFederationRepository {
async fn list_all_followed_remote_actors(&self) -> Result<Vec<RemoteActorInfo>, DomainError> {
let rows = sqlx::query_as::<_, (String, String, Option<String>)>(
"SELECT DISTINCT ar.url, ar.handle, ar.display_name
@@ -40,56 +28,4 @@ impl SocialQueryPort for SqliteFederationRepository {
})
.collect())
}
async fn count_following(&self, user_id: &UserId) -> Result<usize, DomainError> {
let uid = user_id.value().to_string();
let count: i64 = sqlx::query_scalar(
"SELECT COUNT(*) FROM ap_following WHERE local_user_id = ? AND status = 'accepted'",
)
.bind(&uid)
.fetch_one(&self.pool)
.await
.map_err(|e| DomainError::InfrastructureError(e.to_string()))?;
Ok(count as usize)
}
async fn count_accepted_followers(&self, user_id: &UserId) -> Result<usize, DomainError> {
let uid = user_id.value().to_string();
let count: i64 = sqlx::query_scalar(
"SELECT COUNT(*) FROM ap_followers WHERE local_user_id = ? AND status = 'accepted'",
)
.bind(&uid)
.fetch_one(&self.pool)
.await
.map_err(|e| DomainError::InfrastructureError(e.to_string()))?;
Ok(count as usize)
}
async fn get_pending_followers(
&self,
user_id: &UserId,
) -> Result<Vec<PendingFollowerInfo>, DomainError> {
let uid = user_id.value().to_string();
let rows = sqlx::query_as::<_, (String, String, Option<String>, Option<String>)>(
"SELECT ar.url, ar.handle, ar.display_name, ar.avatar_url
FROM ap_followers f
JOIN ap_remote_actors ar ON ar.url = f.remote_actor_url
WHERE f.local_user_id = ? AND f.status = 'pending'",
)
.bind(&uid)
.fetch_all(&self.pool)
.await
.map_err(|e| DomainError::InfrastructureError(e.to_string()))?;
Ok(rows
.into_iter()
.map(
|(url, handle, display_name, avatar_url)| PendingFollowerInfo {
url,
handle,
display_name,
avatar_url,
},
)
.collect())
}
}

View File

@@ -1,6 +1,6 @@
use super::*;
use chrono::Utc;
use domain::ports::SocialQueryPort;
use domain::ports::FederationAdminQuery;
use k_ap::ActorRepository;
use sqlx::SqlitePool;
@@ -79,30 +79,6 @@ async fn setup_db(pool: &SqlitePool) {
.unwrap();
}
#[tokio::test]
async fn test_get_accepted_following_urls_returns_only_accepted() {
let pool = SqlitePool::connect(":memory:").await.unwrap();
setup_db(&pool).await;
let repo = SqliteFederationRepository::new(pool.clone());
let user_id = uuid::Uuid::new_v4();
sqlx::query(
"INSERT INTO ap_following (local_user_id, remote_actor_url, follow_activity_id, status)
VALUES (?, 'https://other.social/users/alice', 'act1', 'accepted'),
(?, 'https://other.social/users/bob', 'act2', 'pending')",
)
.bind(user_id.to_string())
.bind(user_id.to_string())
.execute(&pool)
.await
.unwrap();
let uid = domain::value_objects::UserId::from_uuid(user_id);
let urls = repo.get_accepted_following_urls(&uid).await.unwrap();
assert_eq!(urls.len(), 1);
assert_eq!(urls[0], "https://other.social/users/alice");
}
#[tokio::test]
async fn test_list_all_followed_remote_actors_deduplicates() {
let pool = SqlitePool::connect(":memory:").await.unwrap();