From c072ee95cda26e1823b3114824f6c7f9cf7078d6 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Thu, 14 May 2026 12:07:18 +0200 Subject: [PATCH] =?UTF-8?q?refactor(presentation):=20pure=20HTTP=20library?= =?UTF-8?q?=20=E2=80=94=20remove=20concrete=20adapter=20deps=20and=20binar?= =?UTF-8?q?y?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/bootstrap/src/factory.rs | 1 - crates/presentation/Cargo.toml | 14 ------ crates/presentation/src/lib.rs | 83 +------------------------------- crates/presentation/src/main.rs | 28 ----------- crates/presentation/src/state.rs | 2 - 5 files changed, 1 insertion(+), 127 deletions(-) delete mode 100644 crates/presentation/src/main.rs diff --git a/crates/bootstrap/src/factory.rs b/crates/bootstrap/src/factory.rs index 9426898..5cfbad6 100644 --- a/crates/bootstrap/src/factory.rs +++ b/crates/bootstrap/src/factory.rs @@ -88,7 +88,6 @@ pub async fn build(cfg: &Config) -> Infrastructure { auth: Arc::new(auth::JwtAuthService::new(cfg.jwt_secret.clone(), 86400 * 30)), hasher: Arc::new(auth::Argon2PasswordHasher), events: event_publisher, - fed_config: fed_config.clone(), }; Infrastructure { state, fed_config } diff --git a/crates/presentation/Cargo.toml b/crates/presentation/Cargo.toml index 4ce5adf..0cb30a2 100644 --- a/crates/presentation/Cargo.toml +++ b/crates/presentation/Cargo.toml @@ -3,21 +3,11 @@ name = "presentation" version = "0.1.0" edition = "2021" -[[bin]] -name = "thoughts" -path = "src/main.rs" - [dependencies] domain = { workspace = true } application = { workspace = true } api-types = { workspace = true } -postgres = { workspace = true } -postgres-search = { workspace = true } -auth = { workspace = true } -nats = { workspace = true } -async-nats = { workspace = true } axum = { workspace = true } -sqlx = { workspace = true } tower-http = { workspace = true } tokio = { workspace = true, features = ["full"] } serde = { workspace = true } @@ -25,14 +15,10 @@ serde_json = { workspace = true } uuid = { workspace = true } chrono = { workspace = true } tracing = { workspace = true } -tracing-subscriber = { workspace = true } -dotenvy = { workspace = true } async-trait = { workspace = true } sha2 = "0.10" hex = "0.4" -activitypub = { workspace = true } activitypub-base = { workspace = true } -postgres-federation = { workspace = true } url = { workspace = true } activitypub_federation = "0.7.0-beta.11" utoipa = { version = "5.5.0", features = ["axum_extras", "uuid", "chrono"] } diff --git a/crates/presentation/src/lib.rs b/crates/presentation/src/lib.rs index 74dc9a0..fa5838a 100644 --- a/crates/presentation/src/lib.rs +++ b/crates/presentation/src/lib.rs @@ -1,87 +1,6 @@ pub mod errors; -pub mod openapi; pub mod extractors; pub mod handlers; +pub mod openapi; pub mod routes; pub mod state; - -use std::sync::Arc; -use async_trait::async_trait; -use sqlx::PgPool; -use domain::{errors::DomainError, events::DomainEvent, ports::EventPublisher}; -use postgres_search::PgSearchRepository; -use activitypub_base::{ApFederationConfig, FederationData}; -use activitypub::ThoughtsObjectHandler; -use postgres::activitypub::PgActivityPubRepository; -use postgres_federation::{PostgresApUserRepository, PostgresFederationRepository}; -use state::AppState; - -struct NoOpEventPublisher; -#[async_trait] -impl EventPublisher for NoOpEventPublisher { - async fn publish(&self, _e: &DomainEvent) -> Result<(), DomainError> { Ok(()) } -} - -pub async fn build_state(pool: PgPool, jwt_secret: String) -> AppState { - let event_publisher: Arc = match std::env::var("NATS_URL") { - Ok(url) => match async_nats::connect(&url).await { - Ok(client) => { - tracing::info!("Connected to NATS at {url}"); - Arc::new(nats::NatsEventPublisher::new(client)) - } - Err(e) => { - tracing::warn!("Failed to connect to NATS at {url}: {e} — using no-op publisher"); - Arc::new(NoOpEventPublisher) - } - }, - Err(_) => { - tracing::info!("NATS_URL not set — using no-op event publisher"); - Arc::new(NoOpEventPublisher) - } - }; - - let base_url = std::env::var("BASE_URL") - .unwrap_or_else(|_| "http://localhost:3000".into()); - let allow_registration = std::env::var("ALLOW_REGISTRATION") - .map(|v| v == "true") - .unwrap_or(true); - let fed_debug = std::env::var("RUST_ENV") - .map(|v| v != "production") - .unwrap_or(true); - - let fed_data = FederationData::new( - Arc::new(PostgresFederationRepository::new(pool.clone())), - Arc::new(PostgresApUserRepository::new(pool.clone(), base_url.clone())), - Arc::new(ThoughtsObjectHandler::new( - std::sync::Arc::new(PgActivityPubRepository::new(pool.clone())), - &base_url, - )), - base_url, - allow_registration, - "thoughts".to_string(), - None, - ); - - let fed_config = ApFederationConfig::new(fed_data, fed_debug).await - .expect("federation config failed"); - - AppState { - users: Arc::new(postgres::user::PgUserRepository::new(pool.clone())), - thoughts: Arc::new(postgres::thought::PgThoughtRepository::new(pool.clone())), - likes: Arc::new(postgres::like::PgLikeRepository::new(pool.clone())), - boosts: Arc::new(postgres::boost::PgBoostRepository::new(pool.clone())), - follows: Arc::new(postgres::follow::PgFollowRepository::new(pool.clone())), - blocks: Arc::new(postgres::block::PgBlockRepository::new(pool.clone())), - tags: Arc::new(postgres::tag::PgTagRepository::new(pool.clone())), - api_keys: Arc::new(postgres::api_key::PgApiKeyRepository::new(pool.clone())), - top_friends: Arc::new(postgres::top_friend::PgTopFriendRepository::new(pool.clone())), - notifications: Arc::new(postgres::notification::PgNotificationRepository::new(pool.clone())), - remote_actors: Arc::new(postgres::remote_actor::PgRemoteActorRepository::new(pool.clone())), - feed: Arc::new(postgres::feed::PgFeedRepository::new(pool.clone())), - search: Arc::new(PgSearchRepository::new(pool.clone())), - auth: Arc::new(auth::JwtAuthService::new(jwt_secret, 86400 * 30)), - hasher: Arc::new(auth::Argon2PasswordHasher), - events: event_publisher, - fed_config, - } -} diff --git a/crates/presentation/src/main.rs b/crates/presentation/src/main.rs deleted file mode 100644 index b2af0ef..0000000 --- a/crates/presentation/src/main.rs +++ /dev/null @@ -1,28 +0,0 @@ -use sqlx::PgPool; -use tower_http::cors::CorsLayer; -use tracing_subscriber::EnvFilter; - -#[tokio::main] -async fn main() { - dotenvy::dotenv().ok(); - tracing_subscriber::fmt() - .with_env_filter(EnvFilter::from_default_env()) - .init(); - - let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL required"); - let jwt_secret = std::env::var("JWT_SECRET").expect("JWT_SECRET required"); - let port = std::env::var("PORT").unwrap_or_else(|_| "3000".into()); - - let pool = PgPool::connect(&database_url).await.expect("DB connect failed"); - sqlx::migrate!("../adapters/postgres/migrations").run(&pool).await.expect("Migrations failed"); - - let state = presentation::build_state(pool, jwt_secret).await; - let app = presentation::routes::router(&state.fed_config) - .with_state(state) - .layer(CorsLayer::permissive()); - - let addr = format!("0.0.0.0:{port}"); - tracing::info!("Listening on {addr}"); - let listener = tokio::net::TcpListener::bind(&addr).await.unwrap(); - axum::serve(listener, app).await.unwrap(); -} diff --git a/crates/presentation/src/state.rs b/crates/presentation/src/state.rs index 92ec928..c582001 100644 --- a/crates/presentation/src/state.rs +++ b/crates/presentation/src/state.rs @@ -1,6 +1,5 @@ use std::sync::Arc; use domain::ports::*; -use activitypub_base::ApFederationConfig; #[derive(Clone)] pub struct AppState { @@ -20,5 +19,4 @@ pub struct AppState { pub auth: Arc, pub hasher: Arc, pub events: Arc, - pub fed_config: ApFederationConfig, }