this/server/
entity_registry.rs

1//! Entity registry for managing entity descriptors and auto-generating CRUD routes
2
3use axum::Router;
4use std::collections::HashMap;
5
6/// Trait that describes how to build routes for an entity
7///
8/// Each entity (Order, Invoice, Payment, etc.) should implement this trait
9/// to provide its CRUD routes.
10pub trait EntityDescriptor: Send + Sync {
11    /// The entity type name (singular, e.g., "order")
12    fn entity_type(&self) -> &str;
13
14    /// The plural form (e.g., "orders")
15    fn plural(&self) -> &str;
16
17    /// Build the CRUD routes for this entity
18    ///
19    /// Should return a Router with routes like:
20    /// - GET /{plural}
21    /// - POST /{plural}
22    /// - GET /{plural}/:id
23    fn build_routes(&self) -> Router;
24}
25
26/// Registry for all entities in the application
27///
28/// This registry collects entity descriptors from all registered modules
29/// and can generate a router with all CRUD routes.
30#[derive(Default)]
31pub struct EntityRegistry {
32    descriptors: HashMap<String, Box<dyn EntityDescriptor>>,
33}
34
35impl EntityRegistry {
36    /// Create a new empty registry
37    pub fn new() -> Self {
38        Self {
39            descriptors: HashMap::new(),
40        }
41    }
42
43    /// Register an entity descriptor
44    ///
45    /// The entity type name will be used as the key.
46    pub fn register(&mut self, descriptor: Box<dyn EntityDescriptor>) {
47        let entity_type = descriptor.entity_type().to_string();
48        self.descriptors.insert(entity_type, descriptor);
49    }
50
51    /// Build a router with all registered entity routes
52    ///
53    /// This merges all entity routes into a single router.
54    pub fn build_routes(&self) -> Router {
55        let mut router = Router::new();
56
57        for descriptor in self.descriptors.values() {
58            router = router.merge(descriptor.build_routes());
59        }
60
61        router
62    }
63
64    /// Get all registered entity types
65    pub fn entity_types(&self) -> Vec<&str> {
66        self.descriptors.keys().map(|s| s.as_str()).collect()
67    }
68}