Skip to main content

backbone_pos/
lib.rs

1//! Pos 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/// Stable integration surface for composing services (the deliberate public API consumers depend on).
29pub mod integration;
30// The hand-owned request-pool shim (the composing service's tenant pool
31// resolution): a generated-tree declaration the regenerator drops, so it
32// lives in the preserved block (#447 cause-2 class).
33pub mod request_pool;
34// END CUSTOM
35
36// Re-exports for convenience - Domain entities
37pub use domain::entity::*;
38
39// Re-exports - Infrastructure
40pub use infrastructure::persistence::*;
41
42// Re-exports - Application services
43pub use application::service::PosClosingEntryService;
44pub use application::service::PosInvoiceService;
45pub use application::service::PosInvoiceItemService;
46pub use application::service::PosPaymentService;
47pub use application::service::PosProfileService;
48pub use application::service::PosOpeningEntryService;
49pub use application::service::PosCashMovementService;
50pub use application::service::PosDiscountService;
51pub use application::service::PosManagerPinService;
52pub use application::service::PosFloorPlanService;
53pub use application::service::PosTableService;
54
55// Re-exports - Validation
56pub use application::validator::{ValidationError, ValidationResult};
57
58use std::sync::Arc;
59use axum::Router;
60use sqlx::PgPool;
61
62/// Pos module configuration
63///
64/// Use the builder pattern to configure and register this module:
65///
66/// ```text
67/// let pos = PosModule::builder()
68///     .with_database(pool.clone())
69///     .build()?;
70///
71/// // Unguarded full CRUD (trusted/admin); compose a guarded router for production.
72/// let router = pos.all_crud_routes();
73/// ```
74pub struct PosModule {
75    pub(crate) pos_closing_entry_service: Arc<PosClosingEntryService>,
76    pub(crate) pos_invoice_service: Arc<PosInvoiceService>,
77    pub(crate) pos_invoice_item_service: Arc<PosInvoiceItemService>,
78    pub(crate) pos_payment_service: Arc<PosPaymentService>,
79    pub(crate) pos_profile_service: Arc<PosProfileService>,
80    pub(crate) pos_opening_entry_service: Arc<PosOpeningEntryService>,
81    pub(crate) pos_cash_movement_service: Arc<PosCashMovementService>,
82    pub(crate) pos_discount_service: Arc<PosDiscountService>,
83    pub(crate) pos_manager_pin_service: Arc<PosManagerPinService>,
84    pub(crate) pos_floor_plan_service: Arc<PosFloorPlanService>,
85    pub(crate) pos_table_service: Arc<PosTableService>,
86    // <<< CUSTOM FIELDS
87    // END CUSTOM
88}
89
90impl PosModule {
91    /// Create a new module builder
92    pub fn builder() -> PosModuleBuilder {
93        PosModuleBuilder::new()
94    }
95
96    /// Mount ALL generated CRUD endpoints (12 per entity) with NO domain
97    /// validation — the fully **unguarded** surface. A well-formed request can
98    /// create invalid rows or soft-delete a referenced master out from under its
99    /// dependents. Prefer a guarded composition (read + validated writes) for any
100    /// real deployment; use this only in trusted/admin/seeding contexts.
101    pub fn all_crud_routes(&self) -> Router {
102        use presentation::http::{
103            create_pos_closing_entry_routes,
104            create_pos_invoice_routes,
105            create_pos_invoice_item_routes,
106            create_pos_payment_routes,
107            create_pos_profile_routes,
108            create_pos_opening_entry_routes,
109            create_pos_cash_movement_routes,
110            create_pos_discount_routes,
111            create_pos_manager_pin_routes,
112            create_pos_floor_plan_routes,
113            create_pos_table_routes,
114        };
115
116        Router::new()
117            .merge(create_pos_closing_entry_routes(self.pos_closing_entry_service.clone()))
118            .merge(create_pos_invoice_routes(self.pos_invoice_service.clone()))
119            .merge(create_pos_invoice_item_routes(self.pos_invoice_item_service.clone()))
120            .merge(create_pos_payment_routes(self.pos_payment_service.clone()))
121            .merge(create_pos_profile_routes(self.pos_profile_service.clone()))
122            .merge(create_pos_opening_entry_routes(self.pos_opening_entry_service.clone()))
123            .merge(create_pos_cash_movement_routes(self.pos_cash_movement_service.clone()))
124            .merge(create_pos_discount_routes(self.pos_discount_service.clone()))
125            .merge(create_pos_manager_pin_routes(self.pos_manager_pin_service.clone()))
126            .merge(create_pos_floor_plan_routes(self.pos_floor_plan_service.clone()))
127            .merge(create_pos_table_routes(self.pos_table_service.clone()))
128    }
129
130    /// Deprecated alias for [`Self::all_crud_routes`]. `routes()` reads like
131    /// "the routes" but mounts UNVALIDATED generic CRUD on every entity — a naive
132    /// mount exposes unguarded writes. Compose a guarded router (read + validated
133    /// writes) for production, or call `all_crud_routes()` to opt into the full
134    /// unguarded surface explicitly.
135    #[deprecated(note = "mounts unvalidated generic CRUD; prefer readonly_routes() + validated writes, or all_crud_routes() for the full/unguarded surface")]
136    pub fn routes(&self) -> Router {
137        self.all_crud_routes()
138    }
139
140    /// Read-only routes for every entity (GET endpoints only) — the safe base.
141    ///
142    /// Generic mutation can't reach here, so this surface cannot bypass a
143    /// validated write service's invariants. Use this as the production base and
144    /// merge validated write routes (or a write service's HTTP layer) onto it.
145    pub fn readonly_routes(&self) -> Router {
146        use presentation::http::{
147            create_pos_closing_entry_read_routes,
148            create_pos_invoice_read_routes,
149            create_pos_invoice_item_read_routes,
150            create_pos_payment_read_routes,
151            create_pos_profile_read_routes,
152            create_pos_opening_entry_read_routes,
153            create_pos_cash_movement_read_routes,
154            create_pos_discount_read_routes,
155            create_pos_manager_pin_read_routes,
156            create_pos_floor_plan_read_routes,
157            create_pos_table_read_routes,
158        };
159
160        Router::new()
161            .merge(create_pos_closing_entry_read_routes(self.pos_closing_entry_service.clone()))
162            .merge(create_pos_invoice_read_routes(self.pos_invoice_service.clone()))
163            .merge(create_pos_invoice_item_read_routes(self.pos_invoice_item_service.clone()))
164            .merge(create_pos_payment_read_routes(self.pos_payment_service.clone()))
165            .merge(create_pos_profile_read_routes(self.pos_profile_service.clone()))
166            .merge(create_pos_opening_entry_read_routes(self.pos_opening_entry_service.clone()))
167            .merge(create_pos_cash_movement_read_routes(self.pos_cash_movement_service.clone()))
168            .merge(create_pos_discount_read_routes(self.pos_discount_service.clone()))
169            .merge(create_pos_manager_pin_read_routes(self.pos_manager_pin_service.clone()))
170            .merge(create_pos_floor_plan_read_routes(self.pos_floor_plan_service.clone()))
171            .merge(create_pos_table_read_routes(self.pos_table_service.clone()))
172    }
173
174    // <<< CUSTOM METHODS
175    // END CUSTOM
176}
177
178/// Builder for PosModule
179pub struct PosModuleBuilder {
180    db_pool: Option<PgPool>,
181    // <<< CUSTOM BUILDER FIELDS
182    // END CUSTOM
183}
184
185impl PosModuleBuilder {
186    /// Create a new builder
187    pub fn new() -> Self {
188        Self {
189            db_pool: None,
190            // <<< CUSTOM BUILDER DEFAULTS
191            // END CUSTOM
192        }
193    }
194
195    /// Set the database connection pool
196    pub fn with_database(mut self, pool: PgPool) -> Self {
197        self.db_pool = Some(pool);
198        self
199    }
200
201    // <<< CUSTOM - custom builder methods
202    // END CUSTOM
203
204    /// Build the module with configured dependencies
205    pub fn build(self) -> anyhow::Result<PosModule> {
206        let db_pool = self.db_pool
207            .ok_or_else(|| anyhow::anyhow!("Database pool not configured"))?;
208
209        // PosClosingEntry service
210        let pos_closing_entry_repository = Arc::new(PosClosingEntryRepository::new(db_pool.clone()));
211        let pos_closing_entry_service = Arc::new(PosClosingEntryService::with_repository(pos_closing_entry_repository.clone()));
212
213        // PosInvoice service
214        let pos_invoice_repository = Arc::new(PosInvoiceRepository::new(db_pool.clone()));
215        let pos_invoice_service = Arc::new(PosInvoiceService::with_repository(pos_invoice_repository.clone()));
216
217        // PosInvoiceItem service
218        let pos_invoice_item_repository = Arc::new(PosInvoiceItemRepository::new(db_pool.clone()));
219        let pos_invoice_item_service = Arc::new(PosInvoiceItemService::with_repository(pos_invoice_item_repository.clone()));
220
221        // PosPayment service
222        let pos_payment_repository = Arc::new(PosPaymentRepository::new(db_pool.clone()));
223        let pos_payment_service = Arc::new(PosPaymentService::with_repository(pos_payment_repository.clone()));
224
225        // PosProfile service
226        let pos_profile_repository = Arc::new(PosProfileRepository::new(db_pool.clone()));
227        let pos_profile_service = Arc::new(PosProfileService::with_repository(pos_profile_repository.clone()));
228
229        // PosOpeningEntry service
230        let pos_opening_entry_repository = Arc::new(PosOpeningEntryRepository::new(db_pool.clone()));
231        let pos_opening_entry_service = Arc::new(PosOpeningEntryService::with_repository(pos_opening_entry_repository.clone()));
232
233        // PosCashMovement service
234        let pos_cash_movement_repository = Arc::new(PosCashMovementRepository::new(db_pool.clone()));
235        let pos_cash_movement_service = Arc::new(PosCashMovementService::with_repository(pos_cash_movement_repository.clone()));
236
237        // PosDiscount service
238        let pos_discount_repository = Arc::new(PosDiscountRepository::new(db_pool.clone()));
239        let pos_discount_service = Arc::new(PosDiscountService::with_repository(pos_discount_repository.clone()));
240
241        // PosManagerPin service
242        let pos_manager_pin_repository = Arc::new(PosManagerPinRepository::new(db_pool.clone()));
243        let pos_manager_pin_service = Arc::new(PosManagerPinService::with_repository(pos_manager_pin_repository.clone()));
244
245        // PosFloorPlan service
246        let pos_floor_plan_repository = Arc::new(PosFloorPlanRepository::new(db_pool.clone()));
247        let pos_floor_plan_service = Arc::new(PosFloorPlanService::with_repository(pos_floor_plan_repository.clone()));
248
249        // PosTable service
250        let pos_table_repository = Arc::new(PosTableRepository::new(db_pool.clone()));
251        let pos_table_service = Arc::new(PosTableService::with_repository(pos_table_repository.clone()));
252
253        // <<< CUSTOM
254        // END CUSTOM
255
256        Ok(PosModule {
257            pos_closing_entry_service,
258            pos_invoice_service,
259            pos_invoice_item_service,
260            pos_payment_service,
261            pos_profile_service,
262            pos_opening_entry_service,
263            pos_cash_movement_service,
264            pos_discount_service,
265            pos_manager_pin_service,
266            pos_floor_plan_service,
267            pos_table_service,
268            // <<< CUSTOM
269            // END CUSTOM
270        })
271    }
272}
273
274impl Default for PosModuleBuilder {
275    fn default() -> Self {
276        Self::new()
277    }
278}