refactor: move ap_service from AppState to AppContext.Services

This commit is contained in:
2026-07-10 15:34:23 +02:00
parent 322e9ee81a
commit 3ee75305a9
7 changed files with 21 additions and 19 deletions

View File

@@ -60,6 +60,8 @@ pub struct Services {
pub document_parser: Arc<dyn DocumentParser>, pub document_parser: Arc<dyn DocumentParser>,
pub review_logger: Arc<dyn ReviewLogger>, pub review_logger: Arc<dyn ReviewLogger>,
pub person_enrichment: Option<Arc<dyn PersonEnrichmentClient>>, pub person_enrichment: Option<Arc<dyn PersonEnrichmentClient>>,
#[cfg(feature = "federation")]
pub ap_service: Arc<dyn activitypub::ActivityPubPort>,
} }
#[derive(Clone)] #[derive(Clone)]

View File

@@ -83,7 +83,7 @@ pub async fn get_blocked_domains_admin(
_admin: AdminApiUser, _admin: AdminApiUser,
) -> Result<Json<Vec<BlockedDomainResponse>>, ApiError> { ) -> Result<Json<Vec<BlockedDomainResponse>>, ApiError> {
let domains = state let domains = state
.ap_service .app_ctx.services.ap_service
.get_blocked_domains() .get_blocked_domains()
.await .await
.map_err(ap_to_domain)?; .map_err(ap_to_domain)?;
@@ -115,7 +115,7 @@ pub async fn add_blocked_domain_admin(
axum::Json(body): axum::Json<AddBlockedDomainRequest>, axum::Json(body): axum::Json<AddBlockedDomainRequest>,
) -> Result<impl IntoResponse, ApiError> { ) -> Result<impl IntoResponse, ApiError> {
state state
.ap_service .app_ctx.services.ap_service
.add_blocked_domain(&body.domain, body.reason.as_deref()) .add_blocked_domain(&body.domain, body.reason.as_deref())
.await .await
.map_err(ap_to_domain)?; .map_err(ap_to_domain)?;
@@ -138,7 +138,7 @@ pub async fn remove_blocked_domain_admin(
axum::extract::Path(domain): axum::extract::Path<String>, axum::extract::Path(domain): axum::extract::Path<String>,
) -> Result<impl IntoResponse, ApiError> { ) -> Result<impl IntoResponse, ApiError> {
state state
.ap_service .app_ctx.services.ap_service
.remove_blocked_domain(&domain) .remove_blocked_domain(&domain)
.await .await
.map_err(ap_to_domain)?; .map_err(ap_to_domain)?;
@@ -705,7 +705,7 @@ pub async fn get_followers_collection(
if accept.contains("application/activity+json") || accept.contains("application/ld+json") { if accept.contains("application/activity+json") || accept.contains("application/ld+json") {
let page = params.get("page").and_then(|p| p.parse::<u32>().ok()); let page = params.get("page").and_then(|p| p.parse::<u32>().ok());
return match state return match state
.ap_service .app_ctx.services.ap_service
.followers_collection_json(user_id, page) .followers_collection_json(user_id, page)
.await .await
{ {
@@ -736,7 +736,7 @@ pub async fn get_following_collection(
if accept.contains("application/activity+json") || accept.contains("application/ld+json") { if accept.contains("application/activity+json") || accept.contains("application/ld+json") {
let page = params.get("page").and_then(|p| p.parse::<u32>().ok()); let page = params.get("page").and_then(|p| p.parse::<u32>().ok());
return match state return match state
.ap_service .app_ctx.services.ap_service
.following_collection_json(user_id, page) .following_collection_json(user_id, page)
.await .await
{ {
@@ -770,7 +770,7 @@ pub async fn get_following_page(
"{}/users/{}/following-list", "{}/users/{}/following-list",
state.app_ctx.config.base_url, profile_user_uuid state.app_ctx.config.base_url, profile_user_uuid
); );
match state.ap_service.get_following(user_id.value()).await { match state.app_ctx.services.ap_service.get_following(user_id.value()).await {
Ok(following) => { Ok(following) => {
let actors: Vec<RemoteActorData> = following let actors: Vec<RemoteActorData> = following
.into_iter() .into_iter()
@@ -817,7 +817,7 @@ pub async fn get_followers_page(
state.app_ctx.config.base_url, profile_user_uuid state.app_ctx.config.base_url, profile_user_uuid
); );
match state match state
.ap_service .app_ctx.services.ap_service
.get_accepted_followers(user_id.value()) .get_accepted_followers(user_id.value())
.await .await
{ {
@@ -899,7 +899,7 @@ pub async fn get_blocked_domains_page(
let mut ctx = build_page_context(&state, Some(user_id), csrf.0).await; let mut ctx = build_page_context(&state, Some(user_id), csrf.0).await;
ctx.page_title = "Blocked Domains — Movies Diary".to_string(); ctx.page_title = "Blocked Domains — Movies Diary".to_string();
ctx.canonical_url = format!("{}/admin/blocked-domains", state.app_ctx.config.base_url); ctx.canonical_url = format!("{}/admin/blocked-domains", state.app_ctx.config.base_url);
match state.ap_service.get_blocked_domains().await { match state.app_ctx.services.ap_service.get_blocked_domains().await {
Ok(domains) => { Ok(domains) => {
let entries: Vec<template_askama::BlockedDomainEntry> = domains let entries: Vec<template_askama::BlockedDomainEntry> = domains
.into_iter() .into_iter()
@@ -937,7 +937,7 @@ pub async fn post_blocked_domain(
} }
let reason = form.reason.as_deref().filter(|s| !s.trim().is_empty()); let reason = form.reason.as_deref().filter(|s| !s.trim().is_empty());
match state match state
.ap_service .app_ctx.services.ap_service
.add_blocked_domain(&form.domain, reason) .add_blocked_domain(&form.domain, reason)
.await .await
{ {
@@ -958,7 +958,7 @@ pub async fn post_remove_blocked_domain(
if crate::csrf::mismatch(&csrf, &form.csrf_token) { if crate::csrf::mismatch(&csrf, &form.csrf_token) {
return StatusCode::FORBIDDEN.into_response(); return StatusCode::FORBIDDEN.into_response();
} }
match state.ap_service.remove_blocked_domain(&form.domain).await { match state.app_ctx.services.ap_service.remove_blocked_domain(&form.domain).await {
Ok(()) => Redirect::to("/admin/blocked-domains").into_response(), Ok(()) => Redirect::to("/admin/blocked-domains").into_response(),
Err(e) => { Err(e) => {
tracing::error!("remove_blocked_domain error: {:?}", e); tracing::error!("remove_blocked_domain error: {:?}", e);
@@ -975,7 +975,7 @@ pub async fn get_blocked_actors_page(
let mut ctx = build_page_context(&state, Some(user_id.clone()), csrf.0).await; let mut ctx = build_page_context(&state, Some(user_id.clone()), csrf.0).await;
ctx.page_title = "Blocked Users — Movies Diary".to_string(); ctx.page_title = "Blocked Users — Movies Diary".to_string();
ctx.canonical_url = format!("{}/social/blocked", state.app_ctx.config.base_url); ctx.canonical_url = format!("{}/social/blocked", state.app_ctx.config.base_url);
match state.ap_service.get_blocked_actors(user_id.value()).await { match state.app_ctx.services.ap_service.get_blocked_actors(user_id.value()).await {
Ok(actors) => { Ok(actors) => {
let entries: Vec<template_askama::BlockedActorEntry> = actors let entries: Vec<template_askama::BlockedActorEntry> = actors
.into_iter() .into_iter()

View File

@@ -647,6 +647,8 @@ pub async fn get_user_profile_html(
.unwrap_or(""); .unwrap_or("");
if accept.contains("application/activity+json") || accept.contains("application/ld+json") { if accept.contains("application/activity+json") || accept.contains("application/ld+json") {
return match state return match state
.app_ctx
.services
.ap_service .ap_service
.actor_json(&profile_user_uuid.to_string()) .actor_json(&profile_user_uuid.to_string())
.await .await

View File

@@ -215,6 +215,8 @@ async fn wire_dependencies() -> anyhow::Result<(AppState, axum::Router)> {
document_parser: Arc::new(ImporterDocumentParser) as Arc<dyn DocumentParser>, document_parser: Arc::new(ImporterDocumentParser) as Arc<dyn DocumentParser>,
review_logger, review_logger,
person_enrichment: None, person_enrichment: None,
#[cfg(feature = "federation")]
ap_service,
}, },
config: app_config, config: app_config,
}; };
@@ -224,8 +226,6 @@ async fn wire_dependencies() -> anyhow::Result<(AppState, axum::Router)> {
rss_renderer: Arc::new(RssAdapter::new( rss_renderer: Arc::new(RssAdapter::new(
std::env::var("BASE_URL").unwrap_or_else(|_| "http://localhost:3000".into()), std::env::var("BASE_URL").unwrap_or_else(|_| "http://localhost:3000".into()),
)), )),
#[cfg(feature = "federation")]
ap_service,
}; };
Ok((state, ap_router)) Ok((state, ap_router))
} }

View File

@@ -8,6 +8,4 @@ use domain::ports::RssFeedRenderer;
pub struct AppState { pub struct AppState {
pub app_ctx: AppContext, pub app_ctx: AppContext,
pub rss_renderer: Arc<dyn RssFeedRenderer>, pub rss_renderer: Arc<dyn RssFeedRenderer>,
#[cfg(feature = "federation")]
pub ap_service: Arc<dyn activitypub::ActivityPubPort>,
} }

View File

@@ -834,6 +834,8 @@ pub fn make_test_state(auth_service: Arc<dyn AuthService>) -> crate::state::AppS
document_parser: Arc::clone(&repo) as _, document_parser: Arc::clone(&repo) as _,
review_logger: Arc::clone(&repo) as _, review_logger: Arc::clone(&repo) as _,
person_enrichment: None, person_enrichment: None,
#[cfg(feature = "federation")]
ap_service: Arc::new(activitypub::NoopActivityPubService),
}, },
config: AppConfig { config: AppConfig {
allow_registration: false, allow_registration: false,
@@ -848,8 +850,6 @@ pub fn make_test_state(auth_service: Arc<dyn AuthService>) -> crate::state::AppS
}, },
}, },
rss_renderer: Arc::new(Panic), rss_renderer: Arc::new(Panic),
#[cfg(feature = "federation")]
ap_service: Arc::new(activitypub::NoopActivityPubService),
} }
} }

View File

@@ -487,6 +487,8 @@ async fn test_app() -> Router {
document_parser: Arc::new(PanicDocumentParser), document_parser: Arc::new(PanicDocumentParser),
review_logger: Arc::new(PanicReviewLogger), review_logger: Arc::new(PanicReviewLogger),
person_enrichment: None, person_enrichment: None,
#[cfg(feature = "federation")]
ap_service: Arc::new(activitypub::NoopActivityPubService),
}, },
config: AppConfig { config: AppConfig {
allow_registration: false, allow_registration: false,
@@ -501,8 +503,6 @@ async fn test_app() -> Router {
}, },
}, },
rss_renderer: Arc::new(RssAdapter::new("http://localhost:3000".into())), rss_renderer: Arc::new(RssAdapter::new("http://localhost:3000".into())),
#[cfg(feature = "federation")]
ap_service: Arc::new(activitypub::NoopActivityPubService),
}; };
routes::build_router(state, axum::Router::new()) routes::build_router(state, axum::Router::new())