Skip to main content

backbone_activity/
lib.rs

1//! Activity 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::ActivityService;
38
39use std::sync::Arc;
40use axum::Router;
41use sqlx::PgPool;
42
43/// Activity module configuration
44///
45/// Use the builder pattern to configure and register this module:
46///
47/// ```text
48/// let activity = ActivityModule::builder()
49///     .with_database(pool.clone())
50///     .build()?;
51///
52/// // Unguarded full CRUD (trusted/admin); compose a guarded router for production.
53/// let router = activity.all_crud_routes();
54/// ```
55pub struct ActivityModule {
56    pub(crate) activity_service: Arc<ActivityService>,
57    // <<< CUSTOM FIELDS
58    // END CUSTOM
59}
60
61impl ActivityModule {
62    /// Create a new module builder
63    pub fn builder() -> ActivityModuleBuilder {
64        ActivityModuleBuilder::new()
65    }
66
67    /// Mount ALL generated CRUD endpoints (12 per entity) with NO domain
68    /// validation — the fully **unguarded** surface. A well-formed request can
69    /// create invalid rows or soft-delete a referenced master out from under its
70    /// dependents. Prefer a guarded composition (read + validated writes) for any
71    /// real deployment; use this only in trusted/admin/seeding contexts.
72    pub fn all_crud_routes(&self) -> Router {
73        use presentation::http::{
74            create_activity_routes,
75        };
76
77        Router::new()
78            .merge(create_activity_routes(self.activity_service.clone()))
79    }
80
81    /// Deprecated alias for [`Self::all_crud_routes`]. `routes()` reads like
82    /// "the routes" but mounts UNVALIDATED generic CRUD on every entity — a naive
83    /// mount exposes unguarded writes. Compose a guarded router (read + validated
84    /// writes) for production, or call `all_crud_routes()` to opt into the full
85    /// unguarded surface explicitly.
86    #[deprecated(note = "mounts unvalidated generic CRUD; prefer readonly_routes() + validated writes, or all_crud_routes() for the full/unguarded surface")]
87    pub fn routes(&self) -> Router {
88        self.all_crud_routes()
89    }
90
91    /// Read-only routes for every entity (GET endpoints only) — the safe base.
92    ///
93    /// Generic mutation can't reach here, so this surface cannot bypass a
94    /// validated write service's invariants. Use this as the production base and
95    /// merge validated write routes (or a write service's HTTP layer) onto it.
96    pub fn readonly_routes(&self) -> Router {
97        use presentation::http::{
98            create_activity_read_routes,
99        };
100
101        Router::new()
102            .merge(create_activity_read_routes(self.activity_service.clone()))
103    }
104
105    // <<< CUSTOM METHODS
106    // END CUSTOM
107}
108
109/// Builder for ActivityModule
110pub struct ActivityModuleBuilder {
111    db_pool: Option<PgPool>,
112    // <<< CUSTOM BUILDER FIELDS
113    // END CUSTOM
114}
115
116impl ActivityModuleBuilder {
117    /// Create a new builder
118    pub fn new() -> Self {
119        Self {
120            db_pool: None,
121            // <<< CUSTOM BUILDER DEFAULTS
122            // END CUSTOM
123        }
124    }
125
126    /// Set the database connection pool
127    pub fn with_database(mut self, pool: PgPool) -> Self {
128        self.db_pool = Some(pool);
129        self
130    }
131
132    // <<< CUSTOM - custom builder methods
133    // END CUSTOM
134
135    /// Build the module with configured dependencies
136    pub fn build(self) -> anyhow::Result<ActivityModule> {
137        let db_pool = self.db_pool
138            .ok_or_else(|| anyhow::anyhow!("Database pool not configured"))?;
139
140        // Activity service
141        let activity_repository = Arc::new(ActivityRepository::new(db_pool.clone()));
142        let activity_service = Arc::new(ActivityService::with_repository(activity_repository.clone()));
143
144        // <<< CUSTOM
145        // END CUSTOM
146
147        Ok(ActivityModule {
148            activity_service,
149            // <<< CUSTOM
150            // END CUSTOM
151        })
152    }
153}
154
155impl Default for ActivityModuleBuilder {
156    fn default() -> Self {
157        Self::new()
158    }
159}