refactor: split bootstrap factory into per-context service builders
This commit is contained in:
@@ -7,55 +7,12 @@ use tower_http::{
|
|||||||
trace::TraceLayer,
|
trace::TraceLayer,
|
||||||
};
|
};
|
||||||
|
|
||||||
use adapters_auth::{BcryptPasswordHasher, JwtTokenIssuer};
|
use adapters_postgres::{connect, run_migrations};
|
||||||
|
|
||||||
use adapters_postgres::{
|
|
||||||
PostgresAlbumRepository, PostgresAssetMetadataRepository, PostgresAssetRepository,
|
|
||||||
PostgresDuplicateRepository, PostgresIngestSessionRepository, PostgresJobBatchRepository,
|
|
||||||
PostgresJobRepository, PostgresLibraryPathRepository, PostgresPipelineRepository,
|
|
||||||
PostgresPluginRepository, PostgresQuotaRepository, PostgresShareRepository,
|
|
||||||
PostgresSidecarRepository, PostgresStorageVolumeRepository, PostgresTagRepository,
|
|
||||||
PostgresUsageLedgerRepository, PostgresUserRepository, PostgresVisibilityFilterRepository,
|
|
||||||
connect, run_migrations,
|
|
||||||
};
|
|
||||||
|
|
||||||
use adapters_storage::LocalFileStorage;
|
use adapters_storage::LocalFileStorage;
|
||||||
|
use presentation::{routes::app_router, state::AppState};
|
||||||
use application::{
|
|
||||||
catalog::{
|
|
||||||
GetAssetHandler, GetTimelineHandler, ReadAssetFileHandler, RegisterAssetHandler,
|
|
||||||
UpdateMetadataHandler,
|
|
||||||
},
|
|
||||||
identity::{GetProfileHandler, LoginUserHandler, RegisterUserHandler},
|
|
||||||
organization::{
|
|
||||||
CreateAlbumHandler, GetAlbumHandler, ManageAlbumEntriesHandler, TagAssetHandler,
|
|
||||||
},
|
|
||||||
processing::{
|
|
||||||
CompleteJobHandler, ConfigurePipelineHandler, EnqueueJobHandler, FailJobHandler,
|
|
||||||
ManagePluginHandler, ReportBatchProgressHandler, StartJobHandler,
|
|
||||||
},
|
|
||||||
sharing::{
|
|
||||||
AccessSharedResourceHandler, GenerateShareLinkHandler, RevokeShareHandler,
|
|
||||||
ShareResourceHandler,
|
|
||||||
},
|
|
||||||
sidecar::{
|
|
||||||
DetectExternalChangesHandler, ExportSidecarHandler, FullExportHandler, FullImportHandler,
|
|
||||||
ImportSidecarHandler, ResolveConflictHandler,
|
|
||||||
},
|
|
||||||
storage::{
|
|
||||||
CheckQuotaHandler, IngestAssetHandler, RegisterLibraryPathHandler, RegisterVolumeHandler,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
use presentation::{
|
|
||||||
routes::app_router,
|
|
||||||
state::{
|
|
||||||
AppState, CatalogHandlers, IdentityHandlers, OrganizationHandlers, ProcessingHandlers,
|
|
||||||
SharingHandlers, SidecarHandlers, StorageHandlers,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::log_sidecar_writer::LogSidecarWriter;
|
use crate::services;
|
||||||
|
|
||||||
pub async fn build_app(config: &Config) -> Result<Router> {
|
pub async fn build_app(config: &Config) -> Result<Router> {
|
||||||
let pool = connect(&config.database_url).await?;
|
let pool = connect(&config.database_url).await?;
|
||||||
@@ -64,222 +21,31 @@ pub async fn build_app(config: &Config) -> Result<Router> {
|
|||||||
let nats_client = async_nats::connect(&config.nats_url).await?;
|
let nats_client = async_nats::connect(&config.nats_url).await?;
|
||||||
adapters_nats::ensure_stream(&nats_client).await?;
|
adapters_nats::ensure_stream(&nats_client).await?;
|
||||||
|
|
||||||
// Identity
|
|
||||||
let user_repo = Arc::new(PostgresUserRepository::new(pool.clone()));
|
|
||||||
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));
|
|
||||||
|
|
||||||
// Repos
|
|
||||||
let album_repo = Arc::new(PostgresAlbumRepository::new(pool.clone()));
|
|
||||||
let asset_repo = Arc::new(PostgresAssetRepository::new(pool.clone()));
|
|
||||||
let metadata_repo = Arc::new(PostgresAssetMetadataRepository::new(pool.clone()));
|
|
||||||
let volume_repo = Arc::new(PostgresStorageVolumeRepository::new(pool.clone()));
|
|
||||||
let path_repo = Arc::new(PostgresLibraryPathRepository::new(pool.clone()));
|
|
||||||
let session_repo = Arc::new(PostgresIngestSessionRepository::new(pool.clone()));
|
|
||||||
let quota_repo = Arc::new(PostgresQuotaRepository::new(pool.clone()));
|
|
||||||
let ledger_repo = Arc::new(PostgresUsageLedgerRepository::new(pool.clone()));
|
|
||||||
let tag_repo = Arc::new(PostgresTagRepository::new(pool.clone()));
|
|
||||||
let duplicate_repo = Arc::new(PostgresDuplicateRepository::new(pool.clone()));
|
|
||||||
let sidecar_repo = Arc::new(PostgresSidecarRepository::new(pool.clone()));
|
|
||||||
let job_repo = Arc::new(PostgresJobRepository::new(pool.clone()));
|
|
||||||
let batch_repo = Arc::new(PostgresJobBatchRepository::new(pool.clone()));
|
|
||||||
let plugin_repo = Arc::new(PostgresPluginRepository::new(pool.clone()));
|
|
||||||
let pipeline_repo = Arc::new(PostgresPipelineRepository::new(pool.clone()));
|
|
||||||
let transport = adapters_nats::NatsTransport::new(nats_client);
|
let transport = adapters_nats::NatsTransport::new(nats_client);
|
||||||
let event_publisher: Arc<dyn domain::ports::EventPublisher> =
|
let event_publisher: Arc<dyn domain::ports::EventPublisher> =
|
||||||
Arc::new(event_transport::EventPublisherAdapter::new(transport));
|
Arc::new(event_transport::EventPublisherAdapter::new(transport));
|
||||||
let sidecar_writer: Arc<LogSidecarWriter> = Arc::new(LogSidecarWriter);
|
|
||||||
|
|
||||||
// File storage
|
|
||||||
let storage_path = std::env::var("STORAGE_PATH").unwrap_or_else(|_| "./data/media".to_string());
|
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));
|
let file_storage: Arc<LocalFileStorage> = Arc::new(LocalFileStorage::new(&storage_path));
|
||||||
|
|
||||||
// Album handlers
|
// Build per-context services
|
||||||
let create_album_handler = Arc::new(CreateAlbumHandler::new(album_repo.clone()));
|
let identity = services::identity::build(&pool, &config.jwt_secret);
|
||||||
let get_album_handler = Arc::new(GetAlbumHandler::new(album_repo.clone()));
|
let (storage_repos, storage) = services::storage::build(&pool);
|
||||||
let manage_album_entries_handler = Arc::new(ManageAlbumEntriesHandler::new(album_repo));
|
let catalog = services::catalog::build(&pool, &storage_repos, file_storage, event_publisher.clone());
|
||||||
|
let organization = services::organization::build(&pool);
|
||||||
// Asset handlers
|
let sidecar = services::sidecar::build(&pool);
|
||||||
let ingest_asset_handler = Arc::new(IngestAssetHandler::new(
|
let processing = services::processing::build(&pool, event_publisher.clone());
|
||||||
session_repo,
|
let sharing = services::sharing::build(&pool, event_publisher);
|
||||||
path_repo.clone(),
|
|
||||||
quota_repo.clone(),
|
|
||||||
ledger_repo.clone(),
|
|
||||||
asset_repo.clone(),
|
|
||||||
file_storage.clone(),
|
|
||||||
event_publisher.clone(),
|
|
||||||
));
|
|
||||||
let get_asset_handler = Arc::new(GetAssetHandler::new(
|
|
||||||
asset_repo.clone(),
|
|
||||||
metadata_repo.clone(),
|
|
||||||
));
|
|
||||||
let get_timeline_handler = Arc::new(GetTimelineHandler::new(
|
|
||||||
asset_repo.clone(),
|
|
||||||
metadata_repo.clone(),
|
|
||||||
));
|
|
||||||
let update_metadata_handler = Arc::new(UpdateMetadataHandler::new(
|
|
||||||
asset_repo.clone(),
|
|
||||||
metadata_repo.clone(),
|
|
||||||
event_publisher.clone(),
|
|
||||||
));
|
|
||||||
let read_asset_file_handler =
|
|
||||||
Arc::new(ReadAssetFileHandler::new(asset_repo.clone(), file_storage));
|
|
||||||
|
|
||||||
// Register asset handler
|
|
||||||
let register_asset_handler = Arc::new(RegisterAssetHandler::new(
|
|
||||||
asset_repo.clone(),
|
|
||||||
duplicate_repo,
|
|
||||||
event_publisher.clone(),
|
|
||||||
));
|
|
||||||
|
|
||||||
// Tag handler
|
|
||||||
let tag_asset_handler = Arc::new(TagAssetHandler::new(asset_repo.clone(), tag_repo));
|
|
||||||
|
|
||||||
// Check quota handler
|
|
||||||
let check_quota_handler = Arc::new(CheckQuotaHandler::new(quota_repo, ledger_repo));
|
|
||||||
|
|
||||||
// Sidecar handlers
|
|
||||||
let export_sidecar_handler = Arc::new(ExportSidecarHandler::new(
|
|
||||||
metadata_repo.clone(),
|
|
||||||
sidecar_repo.clone(),
|
|
||||||
sidecar_writer.clone(),
|
|
||||||
));
|
|
||||||
let detect_changes_handler = Arc::new(DetectExternalChangesHandler::new(
|
|
||||||
sidecar_repo.clone(),
|
|
||||||
sidecar_writer.clone(),
|
|
||||||
));
|
|
||||||
let import_sidecar_handler = Arc::new(ImportSidecarHandler::new(
|
|
||||||
sidecar_repo.clone(),
|
|
||||||
sidecar_writer.clone(),
|
|
||||||
metadata_repo.clone(),
|
|
||||||
));
|
|
||||||
let resolve_conflict_handler = Arc::new(ResolveConflictHandler::new(
|
|
||||||
sidecar_repo.clone(),
|
|
||||||
sidecar_writer.clone(),
|
|
||||||
metadata_repo.clone(),
|
|
||||||
));
|
|
||||||
let full_export_handler = Arc::new(FullExportHandler::new(
|
|
||||||
asset_repo.clone(),
|
|
||||||
metadata_repo.clone(),
|
|
||||||
sidecar_repo.clone(),
|
|
||||||
sidecar_writer.clone(),
|
|
||||||
));
|
|
||||||
let full_import_handler = Arc::new(FullImportHandler::new(
|
|
||||||
asset_repo,
|
|
||||||
metadata_repo,
|
|
||||||
sidecar_repo,
|
|
||||||
sidecar_writer,
|
|
||||||
));
|
|
||||||
|
|
||||||
// Processing handlers
|
|
||||||
let enqueue_job_handler = Arc::new(EnqueueJobHandler::new(
|
|
||||||
job_repo.clone(),
|
|
||||||
event_publisher.clone(),
|
|
||||||
));
|
|
||||||
let start_job_handler = Arc::new(StartJobHandler::new(job_repo.clone()));
|
|
||||||
let complete_job_handler = Arc::new(CompleteJobHandler::new(
|
|
||||||
job_repo.clone(),
|
|
||||||
batch_repo.clone(),
|
|
||||||
event_publisher.clone(),
|
|
||||||
));
|
|
||||||
let fail_job_handler = Arc::new(FailJobHandler::new(
|
|
||||||
job_repo.clone(),
|
|
||||||
batch_repo.clone(),
|
|
||||||
event_publisher.clone(),
|
|
||||||
));
|
|
||||||
let batch_progress_handler = Arc::new(ReportBatchProgressHandler::new(batch_repo, job_repo));
|
|
||||||
let manage_plugin_handler = Arc::new(ManagePluginHandler::new(plugin_repo.clone()));
|
|
||||||
let configure_pipeline_handler =
|
|
||||||
Arc::new(ConfigurePipelineHandler::new(pipeline_repo, plugin_repo));
|
|
||||||
|
|
||||||
// Sharing repos & handlers
|
|
||||||
let share_repo = Arc::new(PostgresShareRepository::new(pool.clone()));
|
|
||||||
let _visibility_filter_repo = Arc::new(PostgresVisibilityFilterRepository::new(pool));
|
|
||||||
|
|
||||||
let share_resource_handler = Arc::new(ShareResourceHandler::new(
|
|
||||||
share_repo.clone(),
|
|
||||||
event_publisher.clone(),
|
|
||||||
));
|
|
||||||
let generate_link_handler = Arc::new(GenerateShareLinkHandler::new(share_repo.clone()));
|
|
||||||
let revoke_handler = Arc::new(RevokeShareHandler::new(share_repo.clone(), event_publisher));
|
|
||||||
let access_handler = Arc::new(AccessSharedResourceHandler::new(share_repo));
|
|
||||||
|
|
||||||
// Storage handlers
|
|
||||||
let register_volume_handler = Arc::new(RegisterVolumeHandler::new(volume_repo.clone()));
|
|
||||||
let register_library_path_handler =
|
|
||||||
Arc::new(RegisterLibraryPathHandler::new(volume_repo, path_repo));
|
|
||||||
|
|
||||||
let identity = IdentityHandlers {
|
|
||||||
register: register_handler,
|
|
||||||
login: login_handler,
|
|
||||||
get_profile: get_profile_handler,
|
|
||||||
};
|
|
||||||
|
|
||||||
let catalog = CatalogHandlers {
|
|
||||||
ingest_asset: ingest_asset_handler,
|
|
||||||
get_asset: get_asset_handler,
|
|
||||||
get_timeline: get_timeline_handler,
|
|
||||||
update_metadata: update_metadata_handler,
|
|
||||||
read_asset_file: read_asset_file_handler,
|
|
||||||
register_asset: register_asset_handler,
|
|
||||||
};
|
|
||||||
|
|
||||||
let organization = OrganizationHandlers {
|
|
||||||
create_album: create_album_handler,
|
|
||||||
get_album: get_album_handler,
|
|
||||||
manage_album_entries: manage_album_entries_handler,
|
|
||||||
tag_asset: tag_asset_handler,
|
|
||||||
};
|
|
||||||
|
|
||||||
let storage_handlers = StorageHandlers {
|
|
||||||
register_volume: register_volume_handler,
|
|
||||||
register_library_path: register_library_path_handler,
|
|
||||||
check_quota: check_quota_handler,
|
|
||||||
};
|
|
||||||
|
|
||||||
let sidecar = SidecarHandlers {
|
|
||||||
export: export_sidecar_handler,
|
|
||||||
detect_changes: detect_changes_handler,
|
|
||||||
import: import_sidecar_handler,
|
|
||||||
resolve: resolve_conflict_handler,
|
|
||||||
full_export: full_export_handler,
|
|
||||||
full_import: full_import_handler,
|
|
||||||
};
|
|
||||||
|
|
||||||
let processing = ProcessingHandlers {
|
|
||||||
enqueue_job: enqueue_job_handler,
|
|
||||||
start_job: start_job_handler,
|
|
||||||
complete_job: complete_job_handler,
|
|
||||||
fail_job: fail_job_handler,
|
|
||||||
batch_progress: batch_progress_handler,
|
|
||||||
manage_plugin: manage_plugin_handler,
|
|
||||||
configure_pipeline: configure_pipeline_handler,
|
|
||||||
};
|
|
||||||
|
|
||||||
let sharing = SharingHandlers {
|
|
||||||
share_resource: share_resource_handler,
|
|
||||||
generate_link: generate_link_handler,
|
|
||||||
revoke: revoke_handler,
|
|
||||||
access: access_handler,
|
|
||||||
};
|
|
||||||
|
|
||||||
let state = AppState {
|
let state = AppState {
|
||||||
identity,
|
identity: identity.handlers,
|
||||||
catalog,
|
catalog,
|
||||||
organization,
|
organization,
|
||||||
storage: storage_handlers,
|
storage,
|
||||||
sharing,
|
sharing,
|
||||||
sidecar,
|
sidecar,
|
||||||
processing,
|
processing,
|
||||||
token_issuer: issuer,
|
token_issuer: identity.token_issuer,
|
||||||
};
|
};
|
||||||
|
|
||||||
let cors = CorsLayer::new()
|
let cors = CorsLayer::new()
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod factory;
|
pub mod factory;
|
||||||
pub mod log_sidecar_writer;
|
pub mod log_sidecar_writer;
|
||||||
|
pub mod services;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use tracing::info;
|
|||||||
mod config;
|
mod config;
|
||||||
mod factory;
|
mod factory;
|
||||||
mod log_sidecar_writer;
|
mod log_sidecar_writer;
|
||||||
|
mod services;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
|
|||||||
70
crates/bootstrap/src/services/catalog.rs
Normal file
70
crates/bootstrap/src/services/catalog.rs
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use adapters_postgres::{
|
||||||
|
PgPool, PostgresAssetMetadataRepository, PostgresAssetRepository,
|
||||||
|
PostgresDuplicateRepository,
|
||||||
|
};
|
||||||
|
use adapters_storage::LocalFileStorage;
|
||||||
|
use application::catalog::{
|
||||||
|
GetAssetHandler, GetTimelineHandler, ReadAssetFileHandler, RegisterAssetHandler,
|
||||||
|
UpdateMetadataHandler,
|
||||||
|
};
|
||||||
|
use application::storage::IngestAssetHandler;
|
||||||
|
use domain::ports::EventPublisher;
|
||||||
|
use presentation::state::CatalogHandlers;
|
||||||
|
|
||||||
|
use super::storage::StorageRepos;
|
||||||
|
|
||||||
|
pub fn build(
|
||||||
|
pool: &PgPool,
|
||||||
|
storage_repos: &StorageRepos,
|
||||||
|
file_storage: Arc<LocalFileStorage>,
|
||||||
|
event_publisher: Arc<dyn EventPublisher>,
|
||||||
|
) -> CatalogHandlers {
|
||||||
|
let asset_repo = Arc::new(PostgresAssetRepository::new(pool.clone()));
|
||||||
|
let metadata_repo = Arc::new(PostgresAssetMetadataRepository::new(pool.clone()));
|
||||||
|
let duplicate_repo = Arc::new(PostgresDuplicateRepository::new(pool.clone()));
|
||||||
|
|
||||||
|
let ingest_asset = Arc::new(IngestAssetHandler::new(
|
||||||
|
storage_repos.session_repo.clone(),
|
||||||
|
storage_repos.path_repo.clone(),
|
||||||
|
storage_repos.quota_repo.clone(),
|
||||||
|
storage_repos.ledger_repo.clone(),
|
||||||
|
asset_repo.clone(),
|
||||||
|
file_storage.clone(),
|
||||||
|
event_publisher.clone(),
|
||||||
|
));
|
||||||
|
|
||||||
|
let get_asset = Arc::new(GetAssetHandler::new(
|
||||||
|
asset_repo.clone(),
|
||||||
|
metadata_repo.clone(),
|
||||||
|
));
|
||||||
|
|
||||||
|
let get_timeline = Arc::new(GetTimelineHandler::new(
|
||||||
|
asset_repo.clone(),
|
||||||
|
metadata_repo.clone(),
|
||||||
|
));
|
||||||
|
|
||||||
|
let update_metadata = Arc::new(UpdateMetadataHandler::new(
|
||||||
|
asset_repo.clone(),
|
||||||
|
metadata_repo.clone(),
|
||||||
|
event_publisher.clone(),
|
||||||
|
));
|
||||||
|
|
||||||
|
let read_asset_file = Arc::new(ReadAssetFileHandler::new(asset_repo.clone(), file_storage));
|
||||||
|
|
||||||
|
let register_asset = Arc::new(RegisterAssetHandler::new(
|
||||||
|
asset_repo,
|
||||||
|
duplicate_repo,
|
||||||
|
event_publisher,
|
||||||
|
));
|
||||||
|
|
||||||
|
CatalogHandlers {
|
||||||
|
ingest_asset,
|
||||||
|
get_asset,
|
||||||
|
get_timeline,
|
||||||
|
update_metadata,
|
||||||
|
read_asset_file,
|
||||||
|
register_asset,
|
||||||
|
}
|
||||||
|
}
|
||||||
35
crates/bootstrap/src/services/identity.rs
Normal file
35
crates/bootstrap/src/services/identity.rs
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use adapters_auth::{BcryptPasswordHasher, JwtTokenIssuer};
|
||||||
|
use adapters_postgres::{PgPool, PostgresUserRepository};
|
||||||
|
use application::identity::{GetProfileHandler, LoginUserHandler, RegisterUserHandler};
|
||||||
|
use domain::ports::TokenIssuer;
|
||||||
|
use presentation::state::IdentityHandlers;
|
||||||
|
|
||||||
|
pub struct IdentityServices {
|
||||||
|
pub handlers: IdentityHandlers,
|
||||||
|
pub token_issuer: Arc<dyn TokenIssuer>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build(pool: &PgPool, jwt_secret: &str) -> IdentityServices {
|
||||||
|
let user_repo = Arc::new(PostgresUserRepository::new(pool.clone()));
|
||||||
|
let hasher = Arc::new(BcryptPasswordHasher);
|
||||||
|
let issuer: Arc<JwtTokenIssuer> = Arc::new(JwtTokenIssuer::new(jwt_secret));
|
||||||
|
|
||||||
|
let register = Arc::new(RegisterUserHandler::new(user_repo.clone(), hasher.clone()));
|
||||||
|
let login = Arc::new(LoginUserHandler::new(
|
||||||
|
user_repo.clone(),
|
||||||
|
hasher,
|
||||||
|
issuer.clone(),
|
||||||
|
));
|
||||||
|
let get_profile = Arc::new(GetProfileHandler::new(user_repo));
|
||||||
|
|
||||||
|
IdentityServices {
|
||||||
|
handlers: IdentityHandlers {
|
||||||
|
register,
|
||||||
|
login,
|
||||||
|
get_profile,
|
||||||
|
},
|
||||||
|
token_issuer: issuer,
|
||||||
|
}
|
||||||
|
}
|
||||||
7
crates/bootstrap/src/services/mod.rs
Normal file
7
crates/bootstrap/src/services/mod.rs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
pub mod catalog;
|
||||||
|
pub mod identity;
|
||||||
|
pub mod organization;
|
||||||
|
pub mod processing;
|
||||||
|
pub mod sharing;
|
||||||
|
pub mod sidecar;
|
||||||
|
pub mod storage;
|
||||||
27
crates/bootstrap/src/services/organization.rs
Normal file
27
crates/bootstrap/src/services/organization.rs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use adapters_postgres::{
|
||||||
|
PgPool, PostgresAlbumRepository, PostgresAssetRepository, PostgresTagRepository,
|
||||||
|
};
|
||||||
|
use application::organization::{
|
||||||
|
CreateAlbumHandler, GetAlbumHandler, ManageAlbumEntriesHandler, TagAssetHandler,
|
||||||
|
};
|
||||||
|
use presentation::state::OrganizationHandlers;
|
||||||
|
|
||||||
|
pub fn build(pool: &PgPool) -> OrganizationHandlers {
|
||||||
|
let album_repo = Arc::new(PostgresAlbumRepository::new(pool.clone()));
|
||||||
|
let asset_repo = Arc::new(PostgresAssetRepository::new(pool.clone()));
|
||||||
|
let tag_repo = Arc::new(PostgresTagRepository::new(pool.clone()));
|
||||||
|
|
||||||
|
let create_album = Arc::new(CreateAlbumHandler::new(album_repo.clone()));
|
||||||
|
let get_album = Arc::new(GetAlbumHandler::new(album_repo.clone()));
|
||||||
|
let manage_album_entries = Arc::new(ManageAlbumEntriesHandler::new(album_repo));
|
||||||
|
let tag_asset = Arc::new(TagAssetHandler::new(asset_repo, tag_repo));
|
||||||
|
|
||||||
|
OrganizationHandlers {
|
||||||
|
create_album,
|
||||||
|
get_album,
|
||||||
|
manage_album_entries,
|
||||||
|
tag_asset,
|
||||||
|
}
|
||||||
|
}
|
||||||
48
crates/bootstrap/src/services/processing.rs
Normal file
48
crates/bootstrap/src/services/processing.rs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use adapters_postgres::{
|
||||||
|
PgPool, PostgresJobBatchRepository, PostgresJobRepository, PostgresPipelineRepository,
|
||||||
|
PostgresPluginRepository,
|
||||||
|
};
|
||||||
|
use application::processing::{
|
||||||
|
CompleteJobHandler, ConfigurePipelineHandler, EnqueueJobHandler, FailJobHandler,
|
||||||
|
ManagePluginHandler, ReportBatchProgressHandler, StartJobHandler,
|
||||||
|
};
|
||||||
|
use domain::ports::EventPublisher;
|
||||||
|
use presentation::state::ProcessingHandlers;
|
||||||
|
|
||||||
|
pub fn build(pool: &PgPool, event_publisher: Arc<dyn EventPublisher>) -> ProcessingHandlers {
|
||||||
|
let job_repo = Arc::new(PostgresJobRepository::new(pool.clone()));
|
||||||
|
let batch_repo = Arc::new(PostgresJobBatchRepository::new(pool.clone()));
|
||||||
|
let plugin_repo = Arc::new(PostgresPluginRepository::new(pool.clone()));
|
||||||
|
let pipeline_repo = Arc::new(PostgresPipelineRepository::new(pool.clone()));
|
||||||
|
|
||||||
|
let enqueue_job = Arc::new(EnqueueJobHandler::new(
|
||||||
|
job_repo.clone(),
|
||||||
|
event_publisher.clone(),
|
||||||
|
));
|
||||||
|
let start_job = Arc::new(StartJobHandler::new(job_repo.clone()));
|
||||||
|
let complete_job = Arc::new(CompleteJobHandler::new(
|
||||||
|
job_repo.clone(),
|
||||||
|
batch_repo.clone(),
|
||||||
|
event_publisher.clone(),
|
||||||
|
));
|
||||||
|
let fail_job = Arc::new(FailJobHandler::new(
|
||||||
|
job_repo.clone(),
|
||||||
|
batch_repo.clone(),
|
||||||
|
event_publisher,
|
||||||
|
));
|
||||||
|
let batch_progress = Arc::new(ReportBatchProgressHandler::new(batch_repo, job_repo));
|
||||||
|
let manage_plugin = Arc::new(ManagePluginHandler::new(plugin_repo.clone()));
|
||||||
|
let configure_pipeline = Arc::new(ConfigurePipelineHandler::new(pipeline_repo, plugin_repo));
|
||||||
|
|
||||||
|
ProcessingHandlers {
|
||||||
|
enqueue_job,
|
||||||
|
start_job,
|
||||||
|
complete_job,
|
||||||
|
fail_job,
|
||||||
|
batch_progress,
|
||||||
|
manage_plugin,
|
||||||
|
configure_pipeline,
|
||||||
|
}
|
||||||
|
}
|
||||||
31
crates/bootstrap/src/services/sharing.rs
Normal file
31
crates/bootstrap/src/services/sharing.rs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use adapters_postgres::{
|
||||||
|
PgPool, PostgresShareRepository, PostgresVisibilityFilterRepository,
|
||||||
|
};
|
||||||
|
use application::sharing::{
|
||||||
|
AccessSharedResourceHandler, GenerateShareLinkHandler, RevokeShareHandler,
|
||||||
|
ShareResourceHandler,
|
||||||
|
};
|
||||||
|
use domain::ports::EventPublisher;
|
||||||
|
use presentation::state::SharingHandlers;
|
||||||
|
|
||||||
|
pub fn build(pool: &PgPool, event_publisher: Arc<dyn EventPublisher>) -> SharingHandlers {
|
||||||
|
let share_repo = Arc::new(PostgresShareRepository::new(pool.clone()));
|
||||||
|
let _visibility_filter_repo = Arc::new(PostgresVisibilityFilterRepository::new(pool.clone()));
|
||||||
|
|
||||||
|
let share_resource = Arc::new(ShareResourceHandler::new(
|
||||||
|
share_repo.clone(),
|
||||||
|
event_publisher.clone(),
|
||||||
|
));
|
||||||
|
let generate_link = Arc::new(GenerateShareLinkHandler::new(share_repo.clone()));
|
||||||
|
let revoke = Arc::new(RevokeShareHandler::new(share_repo.clone(), event_publisher));
|
||||||
|
let access = Arc::new(AccessSharedResourceHandler::new(share_repo));
|
||||||
|
|
||||||
|
SharingHandlers {
|
||||||
|
share_resource,
|
||||||
|
generate_link,
|
||||||
|
revoke,
|
||||||
|
access,
|
||||||
|
}
|
||||||
|
}
|
||||||
65
crates/bootstrap/src/services/sidecar.rs
Normal file
65
crates/bootstrap/src/services/sidecar.rs
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use adapters_postgres::{
|
||||||
|
PgPool, PostgresAssetMetadataRepository, PostgresAssetRepository, PostgresSidecarRepository,
|
||||||
|
};
|
||||||
|
use application::sidecar::{
|
||||||
|
DetectExternalChangesHandler, ExportSidecarHandler, FullExportHandler, FullImportHandler,
|
||||||
|
ImportSidecarHandler, ResolveConflictHandler,
|
||||||
|
};
|
||||||
|
use presentation::state::SidecarHandlers;
|
||||||
|
|
||||||
|
use crate::log_sidecar_writer::LogSidecarWriter;
|
||||||
|
|
||||||
|
pub fn build(pool: &PgPool) -> SidecarHandlers {
|
||||||
|
let metadata_repo = Arc::new(PostgresAssetMetadataRepository::new(pool.clone()));
|
||||||
|
let asset_repo = Arc::new(PostgresAssetRepository::new(pool.clone()));
|
||||||
|
let sidecar_repo = Arc::new(PostgresSidecarRepository::new(pool.clone()));
|
||||||
|
let sidecar_writer: Arc<LogSidecarWriter> = Arc::new(LogSidecarWriter);
|
||||||
|
|
||||||
|
let export = Arc::new(ExportSidecarHandler::new(
|
||||||
|
metadata_repo.clone(),
|
||||||
|
sidecar_repo.clone(),
|
||||||
|
sidecar_writer.clone(),
|
||||||
|
));
|
||||||
|
|
||||||
|
let detect_changes = Arc::new(DetectExternalChangesHandler::new(
|
||||||
|
sidecar_repo.clone(),
|
||||||
|
sidecar_writer.clone(),
|
||||||
|
));
|
||||||
|
|
||||||
|
let import = Arc::new(ImportSidecarHandler::new(
|
||||||
|
sidecar_repo.clone(),
|
||||||
|
sidecar_writer.clone(),
|
||||||
|
metadata_repo.clone(),
|
||||||
|
));
|
||||||
|
|
||||||
|
let resolve = Arc::new(ResolveConflictHandler::new(
|
||||||
|
sidecar_repo.clone(),
|
||||||
|
sidecar_writer.clone(),
|
||||||
|
metadata_repo.clone(),
|
||||||
|
));
|
||||||
|
|
||||||
|
let full_export = Arc::new(FullExportHandler::new(
|
||||||
|
asset_repo.clone(),
|
||||||
|
metadata_repo.clone(),
|
||||||
|
sidecar_repo.clone(),
|
||||||
|
sidecar_writer.clone(),
|
||||||
|
));
|
||||||
|
|
||||||
|
let full_import = Arc::new(FullImportHandler::new(
|
||||||
|
asset_repo,
|
||||||
|
metadata_repo,
|
||||||
|
sidecar_repo,
|
||||||
|
sidecar_writer,
|
||||||
|
));
|
||||||
|
|
||||||
|
SidecarHandlers {
|
||||||
|
export,
|
||||||
|
detect_changes,
|
||||||
|
import,
|
||||||
|
resolve,
|
||||||
|
full_export,
|
||||||
|
full_import,
|
||||||
|
}
|
||||||
|
}
|
||||||
46
crates/bootstrap/src/services/storage.rs
Normal file
46
crates/bootstrap/src/services/storage.rs
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use adapters_postgres::{
|
||||||
|
PgPool, PostgresIngestSessionRepository, PostgresLibraryPathRepository,
|
||||||
|
PostgresQuotaRepository, PostgresStorageVolumeRepository, PostgresUsageLedgerRepository,
|
||||||
|
};
|
||||||
|
use application::storage::{CheckQuotaHandler, RegisterLibraryPathHandler, RegisterVolumeHandler};
|
||||||
|
use presentation::state::StorageHandlers;
|
||||||
|
|
||||||
|
/// Shared storage repos needed by other bounded contexts (catalog ingest, etc.).
|
||||||
|
pub struct StorageRepos {
|
||||||
|
pub volume_repo: Arc<PostgresStorageVolumeRepository>,
|
||||||
|
pub path_repo: Arc<PostgresLibraryPathRepository>,
|
||||||
|
pub session_repo: Arc<PostgresIngestSessionRepository>,
|
||||||
|
pub quota_repo: Arc<PostgresQuotaRepository>,
|
||||||
|
pub ledger_repo: Arc<PostgresUsageLedgerRepository>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build(pool: &PgPool) -> (StorageRepos, StorageHandlers) {
|
||||||
|
let volume_repo = Arc::new(PostgresStorageVolumeRepository::new(pool.clone()));
|
||||||
|
let path_repo = Arc::new(PostgresLibraryPathRepository::new(pool.clone()));
|
||||||
|
let session_repo = Arc::new(PostgresIngestSessionRepository::new(pool.clone()));
|
||||||
|
let quota_repo = Arc::new(PostgresQuotaRepository::new(pool.clone()));
|
||||||
|
let ledger_repo = Arc::new(PostgresUsageLedgerRepository::new(pool.clone()));
|
||||||
|
|
||||||
|
let register_volume = Arc::new(RegisterVolumeHandler::new(volume_repo.clone()));
|
||||||
|
let register_library_path =
|
||||||
|
Arc::new(RegisterLibraryPathHandler::new(volume_repo.clone(), path_repo.clone()));
|
||||||
|
let check_quota = Arc::new(CheckQuotaHandler::new(quota_repo.clone(), ledger_repo.clone()));
|
||||||
|
|
||||||
|
let handlers = StorageHandlers {
|
||||||
|
register_volume,
|
||||||
|
register_library_path,
|
||||||
|
check_quota,
|
||||||
|
};
|
||||||
|
|
||||||
|
let repos = StorageRepos {
|
||||||
|
volume_repo,
|
||||||
|
path_repo,
|
||||||
|
session_repo,
|
||||||
|
quota_repo,
|
||||||
|
ledger_repo,
|
||||||
|
};
|
||||||
|
|
||||||
|
(repos, handlers)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user