Skip to main content

backbone_support/
lib.rs

1//! Support Module
2//!
3//! Generated by metaphor-schema. Enhanced with runtime implementations.
4//!
5//! This module provides:
6//! - Domain entities and repositories
7//! - Application services
8//! - HTTP and gRPC handlers
9//! - Route configuration
10//! - State machine enforcement
11//! - Validation rules runtime
12//! - RBAC middleware
13//! - Trigger execution system
14//! - Computed fields
15//! - Workflow orchestrator
16
17#![recursion_limit = "1024"]
18#![allow(unused_imports)]
19
20// Generated modules
21pub mod domain;
22pub mod infrastructure;
23pub mod application;
24pub mod presentation;
25pub mod seeders;
26pub mod exports;
27// <<< CUSTOM MODULES
28// END CUSTOM
29
30// Re-exports for convenience - Domain entities
31pub use domain::entity::*;
32
33// Re-exports - Infrastructure
34pub use infrastructure::persistence::*;
35
36// Re-exports - Application services
37pub use application::service::IssueService;
38pub use application::service::ServiceLevelAgreementService;
39pub use application::service::ServiceLevelPriorityService;
40pub use application::service::WarrantyClaimService;
41
42use std::sync::Arc;
43use axum::Router;
44use sqlx::PgPool;
45
46/// Support module configuration
47///
48/// Use the builder pattern to configure and register this module:
49///
50/// ```text
51/// let support = SupportModule::builder()
52///     .with_database(pool.clone())
53///     .build()?;
54///
55/// // Unguarded full CRUD (trusted/admin); compose a guarded router for production.
56/// let router = support.all_crud_routes();
57/// ```
58pub struct SupportModule {
59    pub(crate) issue_service: Arc<IssueService>,
60    pub(crate) service_level_agreement_service: Arc<ServiceLevelAgreementService>,
61    pub(crate) service_level_priority_service: Arc<ServiceLevelPriorityService>,
62    pub(crate) warranty_claim_service: Arc<WarrantyClaimService>,
63    // <<< CUSTOM FIELDS
64    // END CUSTOM
65}
66
67impl SupportModule {
68    /// Create a new module builder
69    pub fn builder() -> SupportModuleBuilder {
70        SupportModuleBuilder::new()
71    }
72
73    /// Mount ALL generated CRUD endpoints (12 per entity) with NO domain
74    /// validation — the fully **unguarded** surface. A well-formed request can
75    /// create invalid rows or soft-delete a referenced master out from under its
76    /// dependents. Prefer a guarded composition (read + validated writes) for any
77    /// real deployment; use this only in trusted/admin/seeding contexts.
78    pub fn all_crud_routes(&self) -> Router {
79        use presentation::http::{
80            create_issue_routes,
81            create_service_level_agreement_routes,
82            create_service_level_priority_routes,
83            create_warranty_claim_routes,
84        };
85
86        Router::new()
87            .merge(create_issue_routes(self.issue_service.clone()))
88            .merge(create_service_level_agreement_routes(self.service_level_agreement_service.clone()))
89            .merge(create_service_level_priority_routes(self.service_level_priority_service.clone()))
90            .merge(create_warranty_claim_routes(self.warranty_claim_service.clone()))
91    }
92
93    /// Deprecated alias for [`Self::all_crud_routes`]. `routes()` reads like
94    /// "the routes" but mounts UNVALIDATED generic CRUD on every entity — a naive
95    /// mount exposes unguarded writes. Compose a guarded router (read + validated
96    /// writes) for production, or call `all_crud_routes()` to opt into the full
97    /// unguarded surface explicitly.
98    #[deprecated(note = "mounts unvalidated generic CRUD; prefer readonly_routes() + validated writes, or all_crud_routes() for the full/unguarded surface")]
99    pub fn routes(&self) -> Router {
100        self.all_crud_routes()
101    }
102
103    /// Read-only routes for every entity (GET endpoints only) — the safe base.
104    ///
105    /// Generic mutation can't reach here, so this surface cannot bypass a
106    /// validated write service's invariants. Use this as the production base and
107    /// merge validated write routes (or a write service's HTTP layer) onto it.
108    pub fn readonly_routes(&self) -> Router {
109        use presentation::http::{
110            create_issue_read_routes,
111            create_service_level_agreement_read_routes,
112            create_service_level_priority_read_routes,
113            create_warranty_claim_read_routes,
114        };
115
116        Router::new()
117            .merge(create_issue_read_routes(self.issue_service.clone()))
118            .merge(create_service_level_agreement_read_routes(self.service_level_agreement_service.clone()))
119            .merge(create_service_level_priority_read_routes(self.service_level_priority_service.clone()))
120            .merge(create_warranty_claim_read_routes(self.warranty_claim_service.clone()))
121    }
122
123    // <<< CUSTOM METHODS
124    // END CUSTOM
125}
126
127/// Builder for SupportModule
128pub struct SupportModuleBuilder {
129    db_pool: Option<PgPool>,
130    // <<< CUSTOM BUILDER FIELDS
131    // END CUSTOM
132}
133
134impl SupportModuleBuilder {
135    /// Create a new builder
136    pub fn new() -> Self {
137        Self {
138            db_pool: None,
139            // <<< CUSTOM BUILDER DEFAULTS
140            // END CUSTOM
141        }
142    }
143
144    /// Set the database connection pool
145    pub fn with_database(mut self, pool: PgPool) -> Self {
146        self.db_pool = Some(pool);
147        self
148    }
149
150    // <<< CUSTOM - custom builder methods
151    // END CUSTOM
152
153    /// Build the module with configured dependencies
154    pub fn build(self) -> anyhow::Result<SupportModule> {
155        let db_pool = self.db_pool
156            .ok_or_else(|| anyhow::anyhow!("Database pool not configured"))?;
157
158        // Issue service
159        let issue_repository = Arc::new(IssueRepository::new(db_pool.clone()));
160        let issue_service = Arc::new(IssueService::with_repository(issue_repository.clone()));
161
162        // ServiceLevelAgreement service
163        let service_level_agreement_repository = Arc::new(ServiceLevelAgreementRepository::new(db_pool.clone()));
164        let service_level_agreement_service = Arc::new(ServiceLevelAgreementService::with_repository(service_level_agreement_repository.clone()));
165
166        // ServiceLevelPriority service
167        let service_level_priority_repository = Arc::new(ServiceLevelPriorityRepository::new(db_pool.clone()));
168        let service_level_priority_service = Arc::new(ServiceLevelPriorityService::with_repository(service_level_priority_repository.clone()));
169
170        // WarrantyClaim service
171        let warranty_claim_repository = Arc::new(WarrantyClaimRepository::new(db_pool.clone()));
172        let warranty_claim_service = Arc::new(WarrantyClaimService::with_repository(warranty_claim_repository.clone()));
173
174        // <<< CUSTOM
175        // END CUSTOM
176
177        Ok(SupportModule {
178            issue_service,
179            service_level_agreement_service,
180            service_level_priority_service,
181            warranty_claim_service,
182            // <<< CUSTOM
183            // END CUSTOM
184        })
185    }
186}
187
188impl Default for SupportModuleBuilder {
189    fn default() -> Self {
190        Self::new()
191    }
192}