- application: replace flat use_cases/ with identity/{commands,queries}/ and organization/commands/
- each use case now split into Command/Query struct + Handler struct
- api-types: add username to RegisterRequest/UserResponse, add CreateAlbumRequest/AlbumResponse
- presentation: update state, handlers, factory to use new handler types
- tests: restructured to match CQRS module layout, added get_profile tests
57 lines
1.8 KiB
Rust
57 lines
1.8 KiB
Rust
use std::sync::Arc;
|
|
use anyhow::Result;
|
|
use axum::Router;
|
|
use axum::http::HeaderValue;
|
|
use tower_http::{cors::{Any, CorsLayer}, trace::TraceLayer};
|
|
|
|
use adapters_auth::{BcryptPasswordHasher, JwtTokenIssuer};
|
|
|
|
|
|
use adapters_postgres::{connect, run_migrations, PostgresUserRepository};
|
|
|
|
|
|
use adapters_storage::{ObjectStorageAdapter, StorageConfig, build_store};
|
|
|
|
use application::identity::{RegisterUserHandler, LoginUserHandler, GetProfileHandler};
|
|
use presentation::{routes::app_router, state::AppState};
|
|
|
|
use crate::config::Config;
|
|
|
|
pub async fn build_app(config: &Config) -> Result<Router> {
|
|
let pool = connect(&config.database_url).await?;
|
|
run_migrations(&pool).await?;
|
|
|
|
|
|
|
|
let user_repo = Arc::new(PostgresUserRepository::new(pool));
|
|
|
|
let hasher = Arc::new(BcryptPasswordHasher);
|
|
let issuer = Arc::new(JwtTokenIssuer::new(&config.jwt_secret));
|
|
|
|
let register_handler = Arc::new(RegisterUserHandler::new(user_repo.clone(), hasher.clone()));
|
|
let login_handler = Arc::new(LoginUserHandler::new(user_repo.clone(), hasher, issuer.clone()));
|
|
let get_profile_handler = Arc::new(GetProfileHandler::new(user_repo));
|
|
|
|
|
|
let storage_cfg = StorageConfig::from_env()?;
|
|
let store = build_store(&storage_cfg)?;
|
|
let storage = Arc::new(ObjectStorageAdapter::new(store, &storage_cfg.prefix)?);
|
|
|
|
|
|
let state = AppState::new(register_handler, login_handler, get_profile_handler, issuer, storage);
|
|
|
|
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))
|
|
}
|