# MCC Models Standalone Implementation Plan ## Overview This document outlines the plan to make the MCC models in `herodb/src/models/mcc` completely standalone without dependencies on the database implementation, while ensuring that examples like `herodb/src/cmd/dbexample_mcc` can still work. ## Current Architecture Analysis ```mermaid graph TD subgraph "Before" A1[MCC Models] -->|Depends on| B1[DB Implementation] A1 -->|Implements| C1[Model Trait] A1 -->|Implements| D1[Storable Trait] E1[dbexample_mcc] -->|Uses| A1 E1 -->|Uses| B1 end subgraph "After" A2[Standalone MCC Models] -.->|No dependency on| B2[DB Implementation] B2 -->|Works with| F2[Any Serializable Struct] B2 -->|Optional trait| G2[ModelAdapter Trait] E2[dbexample_mcc] -->|Uses| A2 E2 -->|Uses| B2 end ``` ## Implementation Plan ### Phase 1: Make MCC Models Standalone 1. For each MCC model file (calendar.rs, event.rs, mail.rs, contacts.rs, message.rs): - Remove `use crate::db::{Model, Storable, DB, DbError, DbResult}` - Remove `impl Model for X` and `impl Storable for X` blocks - Replace methods that use DB (like `get_events(&self, db: &DB)`) with standalone methods 2. For mod.rs and lib.rs: - Remove `pub use crate::db::{DB, DBBuilder, Model, Storable, DbError, DbResult}` ### Phase 2: Modify DB Implementation 1. Create a new ModelAdapter trait in db/model.rs: ```rust pub trait ModelAdapter { fn get_id(&self) -> u32; fn db_prefix() -> &'static str; fn db_keys(&self) -> Vec { Vec::new() } } ``` 2. Modify DB methods in db.rs to work with any serializable struct: ```rust impl DB { // Generic set method for any serializable type pub fn set(&self, item: &T, id: u32, prefix: &str) -> DbResult<()> { // Implementation } // Enhanced version for types implementing ModelAdapter pub fn set_model(&self, item: &T) -> DbResult<()> { self.set(item, item.get_id(), T::db_prefix()) } // Similar changes for get, delete, list methods } ``` 3. Update DBBuilder to register any serializable type: ```rust impl DBBuilder { pub fn register_type(&mut self, prefix: &'static str) -> &mut Self { // Implementation } pub fn register_model(&mut self) -> &mut Self { self.register_type::(T::db_prefix()) } } ``` ### Phase 3: Update Examples and Tests 1. Update dbexample_mcc/main.rs: ```rust let db = DBBuilder::new(&db_path) .register_type::("calendar") .register_type::("event") // etc. .build()?; ``` 2. Create a new standalone example for MCC models similar to circle_standalone.rs ## Detailed Changes Required ### MCC Models Changes #### calendar.rs - Remove database-related imports - Remove Model and Storable trait implementations - Replace `get_events(&self, db: &DB)` with a standalone method like: ```rust pub fn filter_events(&self, events: &[Event]) -> Vec<&Event> { events.iter() .filter(|event| event.calendar_id == self.id) .collect() } ``` #### event.rs - Remove database-related imports - Remove Model and Storable trait implementations - Add standalone methods for event operations #### mail.rs - Remove database-related imports - Remove Model and Storable trait implementations - Add standalone methods for mail operations #### contacts.rs - Remove database-related imports - Remove Model and Storable trait implementations - Add standalone methods for contact operations #### message.rs - Remove database-related imports - Remove Model and Storable trait implementations - Add standalone methods for message operations #### mod.rs and lib.rs - Remove re-exports of database components ### DB Implementation Changes #### model.rs - Create a new ModelAdapter trait - Keep existing Model and Storable traits for backward compatibility - Add helper methods for working with serializable structs #### db.rs - Modify DB methods to work with any serializable struct - Add overloaded methods for ModelAdapter types - Ensure backward compatibility with existing code #### DBBuilder - Update to register any serializable type - Keep existing methods for backward compatibility ## Testing Strategy 1. Ensure all existing tests pass with the modified DB implementation 2. Create new tests for standalone MCC models 3. Verify dbexample_mcc works with the new implementation 4. Create a new standalone example for MCC models ## Benefits 1. MCC models become more reusable and can be used without database dependencies 2. DB implementation becomes more flexible and can work with any serializable struct 3. Cleaner separation of concerns between models and database operations 4. Easier to test models in isolation