this/core/
module.rs

1//! Module system for This-RS
2//!
3//! Defines traits for microservice modules
4
5use crate::config::LinksConfig;
6use crate::server::entity_registry::EntityRegistry;
7use anyhow::Result;
8use async_trait::async_trait;
9use std::sync::Arc;
10use uuid::Uuid;
11
12/// Trait for fetching entities dynamically
13///
14/// This allows the link system to enrich links with full entity data
15/// without knowing the concrete entity types at compile time.
16#[async_trait]
17pub trait EntityFetcher: Send + Sync {
18    /// Fetch an entity by ID and return it as JSON
19    ///
20    /// # Arguments
21    /// * `entity_id` - The unique ID of the entity to fetch
22    ///
23    /// # Returns
24    /// The entity serialized as JSON, or an error if not found
25    async fn fetch_as_json(&self, entity_id: &Uuid) -> Result<serde_json::Value>;
26
27    /// Get a sample entity for schema introspection
28    ///
29    /// This method returns an entity with all fields populated (can be dummy data)
30    /// to allow the GraphQL schema generator to discover the entity structure.
31    ///
32    /// Default implementation returns an empty object.
33    async fn get_sample_entity(&self) -> Result<serde_json::Value> {
34        Ok(serde_json::json!({}))
35    }
36
37    /// List entities with pagination
38    ///
39    /// # Arguments
40    /// * `limit` - Maximum number of entities to return
41    /// * `offset` - Number of entities to skip
42    ///
43    /// # Returns
44    /// A vector of entities serialized as JSON
45    ///
46    /// Default implementation returns an empty list.
47    async fn list_as_json(
48        &self,
49        _limit: Option<i32>,
50        _offset: Option<i32>,
51    ) -> Result<Vec<serde_json::Value>> {
52        Ok(vec![])
53    }
54}
55
56/// Trait for creating entities dynamically
57///
58/// This allows the link system to create new entities with automatic linking
59/// without knowing the concrete entity types at compile time.
60#[async_trait]
61pub trait EntityCreator: Send + Sync {
62    /// Create a new entity from JSON data
63    ///
64    /// # Arguments
65    /// * `entity_data` - The entity data as JSON
66    ///
67    /// # Returns
68    /// The created entity serialized as JSON (with generated ID, timestamps, etc.)
69    async fn create_from_json(&self, entity_data: serde_json::Value) -> Result<serde_json::Value>;
70
71    /// Update an existing entity from JSON data
72    ///
73    /// # Arguments
74    /// * `entity_id` - The ID of the entity to update
75    /// * `entity_data` - The updated entity data as JSON
76    ///
77    /// # Returns
78    /// The updated entity serialized as JSON
79    ///
80    /// Default implementation returns an error.
81    async fn update_from_json(
82        &self,
83        _entity_id: &Uuid,
84        _entity_data: serde_json::Value,
85    ) -> Result<serde_json::Value> {
86        Err(anyhow::anyhow!(
87            "Update operation not implemented for this entity type"
88        ))
89    }
90
91    /// Delete an entity by ID
92    ///
93    /// # Arguments
94    /// * `entity_id` - The ID of the entity to delete
95    ///
96    /// # Returns
97    /// Ok(()) if successful, error otherwise
98    ///
99    /// Default implementation returns an error.
100    async fn delete(&self, _entity_id: &Uuid) -> Result<()> {
101        Err(anyhow::anyhow!(
102            "Delete operation not implemented for this entity type"
103        ))
104    }
105}
106
107/// Trait for a microservice module
108pub trait Module: Send + Sync {
109    /// Unique module name
110    fn name(&self) -> &str;
111
112    /// Module version
113    fn version(&self) -> &str {
114        "1.0.0"
115    }
116
117    /// List of entity types managed by this module
118    fn entity_types(&self) -> Vec<&str>;
119
120    /// Load links configuration
121    fn links_config(&self) -> Result<LinksConfig>;
122
123    /// Register entities with the entity registry
124    ///
125    /// This method should register all entity descriptors for the module.
126    /// Each entity descriptor provides the CRUD routes for that entity.
127    fn register_entities(&self, registry: &mut EntityRegistry);
128
129    /// Get an entity fetcher for a specific entity type
130    ///
131    /// This allows the framework to dynamically load entities when enriching links.
132    ///
133    /// # Arguments
134    /// * `entity_type` - The type of entity (e.g., "order", "invoice")
135    ///
136    /// # Returns
137    /// An `EntityFetcher` implementation, or `None` if the entity type is not managed by this module
138    fn get_entity_fetcher(&self, entity_type: &str) -> Option<Arc<dyn EntityFetcher>>;
139
140    /// Get an entity creator for a specific entity type
141    ///
142    /// This allows the framework to create new entities dynamically when creating linked entities.
143    ///
144    /// # Arguments
145    /// * `entity_type` - The type of entity (e.g., "order", "invoice")
146    ///
147    /// # Returns
148    /// An `EntityCreator` implementation, or `None` if the entity type is not managed by this module
149    fn get_entity_creator(&self, entity_type: &str) -> Option<Arc<dyn EntityCreator>>;
150}