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