use std::sync::Arc; use libertas_core::{ config::AppConfig, error::{CoreError, CoreResult}, }; use libertas_infra::factory::{ build_album_repository, build_album_share_repository, build_database_pool, build_face_region_repository, build_media_metadata_repository, build_media_repository, build_person_repository, build_person_share_repository, build_tag_repository, build_user_repository, }; use crate::{ security::{Argon2Hasher, JwtGenerator}, services::{ album_service::AlbumServiceImpl, authorization_service::AuthorizationServiceImpl, media_service::MediaServiceImpl, person_service::PersonServiceImpl, tag_service::TagServiceImpl, user_service::UserServiceImpl, }, state::AppState, }; pub async fn build_app_state(config: AppConfig) -> CoreResult { let nats_client = async_nats::connect(&config.broker_url) .await .map_err(|e| CoreError::Config(format!("Failed to connect to NATS: {}", e)))?; println!("API connected to NATS at {}", config.broker_url); let db_pool = build_database_pool(&config.database).await?; let user_repo = build_user_repository(&config.database, db_pool.clone()).await?; let media_repo = build_media_repository(&config, db_pool.clone()).await?; let album_repo = build_album_repository(&config.database, db_pool.clone()).await?; let album_share_repo = build_album_share_repository(&config.database, db_pool.clone()).await?; let media_metadata_repo = build_media_metadata_repository(&config.database, db_pool.clone()).await?; let tag_repo = build_tag_repository(&config.database, db_pool.clone()).await?; let person_repo = build_person_repository(&config.database, db_pool.clone()).await?; let face_region_repo = build_face_region_repository(&config.database, db_pool.clone()).await?; let person_share_repo = build_person_share_repository(&config.database, db_pool.clone()).await?; let hasher = Arc::new(Argon2Hasher::default()); let tokenizer = Arc::new(JwtGenerator::new(config.jwt_secret.clone())); let authorization_service = Arc::new(AuthorizationServiceImpl::new( media_repo.clone(), album_repo.clone(), album_share_repo.clone(), person_repo.clone(), person_share_repo.clone(), face_region_repo.clone(), user_repo.clone(), )); let user_service = Arc::new(UserServiceImpl::new( user_repo.clone(), hasher, tokenizer.clone(), Arc::new(config.clone()), )); let media_service = Arc::new(MediaServiceImpl::new( media_repo.clone(), user_repo.clone(), media_metadata_repo.clone(), authorization_service.clone(), config.clone(), nats_client.clone(), )); let album_service = Arc::new(AlbumServiceImpl::new( album_repo.clone(), album_share_repo.clone(), authorization_service.clone(), )); let tag_service = Arc::new(TagServiceImpl::new( tag_repo.clone(), authorization_service.clone(), )); let person_service = Arc::new(PersonServiceImpl::new( person_repo.clone(), face_region_repo.clone(), person_share_repo.clone(), authorization_service.clone(), )); Ok(AppState { user_service, media_service, album_service, tag_service, person_service, authorization_service, token_generator: tokenizer, nats_client, config, }) }