backbone_maintenance/
lib.rs1#![recursion_limit = "1024"]
18#![allow(unused_imports)]
19
20pub mod domain;
22pub mod infrastructure;
23pub mod application;
24pub mod presentation;
25pub mod seeders;
26pub mod exports;
27
28pub mod maintenance_module_ext;
33pub use domain::entity::*;
36
37pub use infrastructure::persistence::*;
39
40pub use application::service::MaintenanceRequestService;
42pub use application::service::MaintenanceScheduleService;
43pub use application::service::MaintenanceStageService;
44pub use application::service::MaintenanceVisitService;
45pub use application::service::MaintenanceVisitPartService;
46
47pub use application::validator::{ValidationError, ValidationResult};
49
50pub use application::workflows::*;
52
53pub use application::service::{
57 GlPostSink, InventoryPort, LoggingSink, MaintenanceEventSink, MaintenanceWriteService,
58 MaintenanceRequestWriteService,
59};
60use std::sync::Arc;
62use axum::Router;
63use sqlx::PgPool;
64
65pub struct MaintenanceModule {
78 pub(crate) maintenance_request_service: Arc<MaintenanceRequestService>,
79 pub(crate) maintenance_schedule_service: Arc<MaintenanceScheduleService>,
80 pub(crate) maintenance_stage_service: Arc<MaintenanceStageService>,
81 pub(crate) maintenance_visit_service: Arc<MaintenanceVisitService>,
82 pub(crate) maintenance_visit_part_service: Arc<MaintenanceVisitPartService>,
83 pub(crate) query: Arc<dyn crate::exports::MaintenanceQueryService>,
86 pub(crate) write_svc: Arc<application::service::MaintenanceWriteService>,
89 pub(crate) request_write_svc: Arc<application::service::MaintenanceRequestWriteService>,
92 pub(crate) gl_sink: Option<Arc<dyn application::service::GlPostSink>>,
93 pub(crate) inventory_port: Option<Arc<dyn application::service::InventoryPort>>,
94 pub(crate) event_sink: Arc<dyn application::service::MaintenanceEventSink>,
95 }
97
98impl MaintenanceModule {
99 pub fn builder() -> MaintenanceModuleBuilder {
101 MaintenanceModuleBuilder::new()
102 }
103
104 pub fn all_crud_routes(&self) -> Router {
110 use presentation::http::{
111 create_maintenance_request_routes,
112 create_maintenance_schedule_routes,
113 create_maintenance_stage_routes,
114 create_maintenance_visit_routes,
115 create_maintenance_visit_part_routes,
116 };
117
118 Router::new()
119 .merge(create_maintenance_request_routes(self.maintenance_request_service.clone()))
120 .merge(create_maintenance_schedule_routes(self.maintenance_schedule_service.clone()))
121 .merge(create_maintenance_stage_routes(self.maintenance_stage_service.clone()))
122 .merge(create_maintenance_visit_routes(self.maintenance_visit_service.clone()))
123 .merge(create_maintenance_visit_part_routes(self.maintenance_visit_part_service.clone()))
124 }
125
126 #[deprecated(note = "mounts unvalidated generic CRUD; prefer readonly_routes() + validated writes, or all_crud_routes() for the full/unguarded surface")]
132 pub fn routes(&self) -> Router {
133 self.all_crud_routes()
134 }
135
136 pub fn readonly_routes(&self) -> Router {
142 use presentation::http::{
143 create_maintenance_request_read_routes,
144 create_maintenance_schedule_read_routes,
145 create_maintenance_stage_read_routes,
146 create_maintenance_visit_read_routes,
147 create_maintenance_visit_part_read_routes,
148 };
149
150 Router::new()
151 .merge(create_maintenance_request_read_routes(self.maintenance_request_service.clone()))
152 .merge(create_maintenance_schedule_read_routes(self.maintenance_schedule_service.clone()))
153 .merge(create_maintenance_stage_read_routes(self.maintenance_stage_service.clone()))
154 .merge(create_maintenance_visit_read_routes(self.maintenance_visit_service.clone()))
155 .merge(create_maintenance_visit_part_read_routes(self.maintenance_visit_part_service.clone()))
156 }
157
158 }
161
162pub struct MaintenanceModuleBuilder {
164 db_pool: Option<PgPool>,
165 gl_sink: Option<Arc<dyn application::service::GlPostSink>>,
167 inventory_port: Option<Arc<dyn application::service::InventoryPort>>,
168 event_sink: Option<Arc<dyn application::service::MaintenanceEventSink>>,
169 }
171
172impl MaintenanceModuleBuilder {
173 pub fn new() -> Self {
175 Self {
176 db_pool: None,
177 gl_sink: None,
178 inventory_port: None,
179 event_sink: None,
180 }
181 }
182
183 pub fn with_database(mut self, pool: PgPool) -> Self {
185 self.db_pool = Some(pool);
186 self
187 }
188
189 pub fn with_gl_sink(mut self, sink: Arc<dyn application::service::GlPostSink>) -> Self {
194 self.gl_sink = Some(sink);
195 self
196 }
197
198 pub fn with_inventory_port(
201 mut self,
202 port: Arc<dyn application::service::InventoryPort>,
203 ) -> Self {
204 self.inventory_port = Some(port);
205 self
206 }
207
208 pub fn with_event_sink(
210 mut self,
211 sink: Arc<dyn application::service::MaintenanceEventSink>,
212 ) -> Self {
213 self.event_sink = Some(sink);
214 self
215 }
216 pub fn build(self) -> anyhow::Result<MaintenanceModule> {
220 let db_pool = self.db_pool
221 .ok_or_else(|| anyhow::anyhow!("Database pool not configured"))?;
222
223 let maintenance_request_repository = Arc::new(MaintenanceRequestRepository::new(db_pool.clone()));
225 let maintenance_request_service = Arc::new(MaintenanceRequestService::with_repository(maintenance_request_repository.clone()));
226
227 let maintenance_schedule_repository = Arc::new(MaintenanceScheduleRepository::new(db_pool.clone()));
229 let maintenance_schedule_service = Arc::new(MaintenanceScheduleService::with_repository(maintenance_schedule_repository.clone()));
230
231 let maintenance_stage_repository = Arc::new(MaintenanceStageRepository::new(db_pool.clone()));
233 let maintenance_stage_service = Arc::new(MaintenanceStageService::with_repository(maintenance_stage_repository.clone()));
234
235 let maintenance_visit_repository = Arc::new(MaintenanceVisitRepository::new(db_pool.clone()));
237 let maintenance_visit_service = Arc::new(MaintenanceVisitService::with_repository(maintenance_visit_repository.clone()));
238
239 let maintenance_visit_part_repository = Arc::new(MaintenanceVisitPartRepository::new(db_pool.clone()));
241 let maintenance_visit_part_service = Arc::new(MaintenanceVisitPartService::with_repository(maintenance_visit_part_repository.clone()));
242
243 let query: Arc<dyn crate::exports::MaintenanceQueryService> =
245 Arc::new(application::service::MaintenanceQueryServiceImpl::new(db_pool.clone()));
246 let write_svc =
247 Arc::new(application::service::MaintenanceWriteService::new(db_pool.clone()));
248 let request_write_svc = Arc::new(
249 application::service::MaintenanceRequestWriteService::new(db_pool.clone()),
250 );
251 let event_sink: Arc<dyn application::service::MaintenanceEventSink> = self
252 .event_sink
253 .unwrap_or_else(|| Arc::new(application::service::LoggingSink));
254 Ok(MaintenanceModule {
257 maintenance_request_service,
258 maintenance_schedule_service,
259 maintenance_stage_service,
260 maintenance_visit_service,
261 maintenance_visit_part_service,
262 query,
263 write_svc,
264 request_write_svc,
265 gl_sink: self.gl_sink,
266 inventory_port: self.inventory_port,
267 event_sink,
268 })
269 }
270}
271
272impl Default for MaintenanceModuleBuilder {
273 fn default() -> Self {
274 Self::new()
275 }
276}