#![recursion_limit = "1024"]
#![allow(unused_imports)]
pub mod domain;
pub mod infrastructure;
pub mod application;
pub mod presentation;
pub mod seeders;
pub mod exports;
pub use domain::entity::*;
pub use domain::state_machine::*;
pub use infrastructure::persistence::*;
pub use application::service::MailingAbTestService;
pub use application::service::MailingAudienceService;
pub use application::service::MailingContactService;
pub use application::service::MailingSubscriptionService;
pub use application::service::OptOutReasonService;
pub use application::service::MailingService;
pub use application::service::MailingTraceService;
pub use application::service::MailingFilterService;
pub use application::validator::{ValidationError, ValidationResult};
use std::sync::Arc;
use axum::Router;
use sqlx::PgPool;
pub struct MailingModule {
pub(crate) mailing_ab_test_service: Arc<MailingAbTestService>,
pub(crate) mailing_audience_service: Arc<MailingAudienceService>,
pub(crate) mailing_contact_service: Arc<MailingContactService>,
pub(crate) mailing_subscription_service: Arc<MailingSubscriptionService>,
pub(crate) opt_out_reason_service: Arc<OptOutReasonService>,
pub(crate) mailing_service: Arc<MailingService>,
pub(crate) mailing_trace_service: Arc<MailingTraceService>,
pub(crate) mailing_filter_service: Arc<MailingFilterService>,
pub(crate) trace_clicks: crate::application::service::trace_click_ports::TraceClickSlot,
pub(crate) trace_route_service:
std::sync::Arc<crate::application::service::trace_route_service::TraceRouteService>,
}
impl MailingModule {
pub fn builder() -> MailingModuleBuilder {
MailingModuleBuilder::new()
}
pub fn all_crud_routes(&self) -> Router {
use presentation::http::{
create_mailing_ab_test_routes,
create_mailing_audience_routes,
create_mailing_contact_routes,
create_mailing_subscription_routes,
create_opt_out_reason_routes,
create_mailing_read_routes,
create_mailing_trace_read_routes,
create_mailing_filter_routes,
};
Router::new()
.merge(create_mailing_ab_test_routes(self.mailing_ab_test_service.clone()))
.merge(create_mailing_audience_routes(self.mailing_audience_service.clone()))
.merge(create_mailing_contact_routes(self.mailing_contact_service.clone()))
.merge(create_mailing_subscription_routes(self.mailing_subscription_service.clone()))
.merge(create_opt_out_reason_routes(self.opt_out_reason_service.clone()))
.merge(create_mailing_read_routes(self.mailing_service.clone()))
.merge(create_mailing_trace_read_routes(self.mailing_trace_service.clone()))
.merge(create_mailing_filter_routes(self.mailing_filter_service.clone()))
}
#[deprecated(note = "mounts unvalidated generic CRUD; prefer readonly_routes() + validated writes, or all_crud_routes() for the full/unguarded surface")]
pub fn routes(&self) -> Router {
self.all_crud_routes()
}
pub fn readonly_routes(&self) -> Router {
use presentation::http::{
create_mailing_ab_test_read_routes,
create_mailing_audience_read_routes,
create_mailing_contact_read_routes,
create_mailing_subscription_read_routes,
create_opt_out_reason_read_routes,
create_mailing_read_routes,
create_mailing_trace_read_routes,
create_mailing_filter_read_routes,
};
Router::new()
.merge(create_mailing_ab_test_read_routes(self.mailing_ab_test_service.clone()))
.merge(create_mailing_audience_read_routes(self.mailing_audience_service.clone()))
.merge(create_mailing_contact_read_routes(self.mailing_contact_service.clone()))
.merge(create_mailing_subscription_read_routes(self.mailing_subscription_service.clone()))
.merge(create_opt_out_reason_read_routes(self.opt_out_reason_service.clone()))
.merge(create_mailing_read_routes(self.mailing_service.clone()))
.merge(create_mailing_trace_read_routes(self.mailing_trace_service.clone()))
.merge(create_mailing_filter_read_routes(self.mailing_filter_service.clone()))
}
pub fn set_trace_click_port(
&self,
port: std::sync::Arc<dyn crate::application::service::trace_click_ports::TraceClickPort>,
) {
self.trace_clicks.install(port);
}
pub fn public_trace_routes(&self) -> Router {
crate::presentation::http::trace_routes::public_composer(
self.trace_route_service.clone(),
)
}
}
pub struct MailingModuleBuilder {
db_pool: Option<PgPool>,
}
impl MailingModuleBuilder {
pub fn new() -> Self {
Self {
db_pool: None,
}
}
pub fn with_database(mut self, pool: PgPool) -> Self {
self.db_pool = Some(pool);
self
}
pub fn build(self) -> anyhow::Result<MailingModule> {
let db_pool = self.db_pool
.ok_or_else(|| anyhow::anyhow!("Database pool not configured"))?;
let mailing_ab_test_repository = Arc::new(MailingAbTestRepository::new(db_pool.clone()));
let mailing_ab_test_service = Arc::new(MailingAbTestService::with_repository(mailing_ab_test_repository.clone()));
let mailing_audience_repository = Arc::new(MailingAudienceRepository::new(db_pool.clone()));
let mailing_audience_service = Arc::new(MailingAudienceService::with_repository(mailing_audience_repository.clone()));
let mailing_contact_repository = Arc::new(MailingContactRepository::new(db_pool.clone()));
let mailing_contact_service = Arc::new(MailingContactService::with_repository(mailing_contact_repository.clone()));
let mailing_subscription_repository = Arc::new(MailingSubscriptionRepository::new(db_pool.clone()));
let mailing_subscription_service = Arc::new(MailingSubscriptionService::with_repository(mailing_subscription_repository.clone()));
let opt_out_reason_repository = Arc::new(OptOutReasonRepository::new(db_pool.clone()));
let opt_out_reason_service = Arc::new(OptOutReasonService::with_repository(opt_out_reason_repository.clone()));
let mailing_repository = Arc::new(MailingRepository::new(db_pool.clone()));
let mailing_service = Arc::new(MailingService::with_repository(mailing_repository.clone()));
let mailing_trace_repository = Arc::new(MailingTraceRepository::new(db_pool.clone()));
let mailing_trace_service = Arc::new(MailingTraceService::with_repository(mailing_trace_repository.clone()));
let mailing_filter_repository = Arc::new(MailingFilterRepository::new(db_pool.clone()));
let mailing_filter_service = Arc::new(MailingFilterService::with_repository(mailing_filter_repository.clone()));
let trace_clicks =
crate::application::service::trace_click_ports::TraceClickSlot::default();
let trace_route_service = std::sync::Arc::new(
crate::application::service::trace_route_service::TraceRouteService::new(
db_pool.clone(),
trace_clicks.clone(),
),
);
Ok(MailingModule {
mailing_ab_test_service,
mailing_audience_service,
mailing_contact_service,
mailing_subscription_service,
opt_out_reason_service,
mailing_service,
mailing_trace_service,
mailing_filter_service,
trace_clicks,
trace_route_service,
})
}
}
impl Default for MailingModuleBuilder {
fn default() -> Self {
Self::new()
}
}