71 lines
2.5 KiB
Rust
71 lines
2.5 KiB
Rust
use anyhow::Result;
|
|
use axum::Router;
|
|
use axum::http::HeaderValue;
|
|
use std::sync::Arc;
|
|
use tower_http::{
|
|
cors::{Any, CorsLayer},
|
|
trace::TraceLayer,
|
|
};
|
|
|
|
use adapters_postgres::{connect, run_migrations};
|
|
use adapters_storage::LocalFileStorage;
|
|
use presentation::{routes::app_router, state::AppState};
|
|
|
|
use crate::config::Config;
|
|
use crate::services;
|
|
|
|
pub async fn build_app(config: &Config) -> Result<Router> {
|
|
let pool = connect(&config.database_url).await?;
|
|
run_migrations(&pool).await?;
|
|
|
|
let nats_client = async_nats::connect(&config.nats_url).await?;
|
|
adapters_nats::ensure_stream(&nats_client).await?;
|
|
|
|
let transport = adapters_nats::NatsTransport::new(nats_client);
|
|
let nats_publisher: Arc<dyn domain::ports::EventPublisher> =
|
|
Arc::new(event_transport::EventPublisherAdapter::new(transport));
|
|
let event_store: Arc<dyn domain::ports::EventStore> =
|
|
Arc::new(adapters_postgres::PostgresEventStore::new(pool.clone()));
|
|
let event_publisher: Arc<dyn domain::ports::EventPublisher> =
|
|
Arc::new(event_transport::CompositeEventPublisher::new(nats_publisher, event_store));
|
|
|
|
let storage_path = std::env::var("STORAGE_PATH").unwrap_or_else(|_| "./data/media".to_string());
|
|
let file_storage: Arc<LocalFileStorage> = Arc::new(LocalFileStorage::new(&storage_path));
|
|
|
|
// Build per-context services
|
|
let identity = services::identity::build(&pool, &config.jwt_secret);
|
|
let (storage_repos, storage) = services::storage::build(&pool);
|
|
let catalog = services::catalog::build(&pool, &storage_repos, file_storage, event_publisher.clone());
|
|
let organization = services::organization::build(&pool);
|
|
let sidecar = services::sidecar::build(&pool);
|
|
let processing = services::processing::build(&pool, event_publisher.clone());
|
|
let sharing = services::sharing::build(&pool, event_publisher);
|
|
|
|
let state = AppState {
|
|
identity: identity.handlers,
|
|
catalog,
|
|
organization,
|
|
storage,
|
|
sharing,
|
|
sidecar,
|
|
processing,
|
|
token_issuer: identity.token_issuer,
|
|
};
|
|
|
|
let cors = CorsLayer::new()
|
|
.allow_origin(
|
|
config
|
|
.cors_allowed_origins
|
|
.iter()
|
|
.filter_map(|o| o.parse::<HeaderValue>().ok())
|
|
.collect::<Vec<_>>(),
|
|
)
|
|
.allow_methods(Any)
|
|
.allow_headers(Any);
|
|
|
|
Ok(app_router()
|
|
.with_state(state)
|
|
.layer(TraceLayer::new_for_http())
|
|
.layer(cors))
|
|
}
|