# Rustelo Layered Override System ## 🎯 Architecture Overview The layered override system enables customization at multiple levels while maintaining framework integrity and update safety. This system follows a clear precedence hierarchy: **Precedence Order**: `Local > Feature > Template > Framework` ## 🏗️ Layer Definitions ### 1. Framework Layer (Bottom - Never Modified) - **Location**: Framework crates in dependencies - **Content**: Core rustelo functionality - **Modification**: ❌ Never modified directly - **Updates**: Automatic via `cargo rustelo update` ### 2. Template Layer (Foundation) - **Location**: Project templates from `/rustelo/templates/` - **Content**: Default project structure and configurations - **Modification**: ❌ Not modified directly in projects - **Updates**: Synced via `cargo rustelo sync templates` ### 3. Feature Layer (Additive) - **Location**: Feature-specific additions from `/rustelo/features/*/templates/` - **Content**: Feature configurations, dependencies, tooling - **Modification**: ✅ Can be overridden by local layer - **Updates**: Managed via `cargo rustelo add/remove ` ### 4. Local Layer (Top - Full Control) - **Location**: Project-specific files and customizations - **Content**: Local customizations, overrides, project-specific code - **Modification**: ✅ Full control by developers - **Updates**: Always preserved during framework updates ## 🔧 Override Resolution Process ### Configuration Files (Cargo.toml, justfile, package.json) ``` Resolution Order: 1. Check for local override: `config/local/Cargo.toml` 2. Check for feature configs: `config/features/*/Cargo.toml` 3. Check template default: `config/templates/Cargo.toml` 4. Fall back to framework defaults ``` **Merge Strategy**: Hierarchical merge with higher layers taking precedence ### Component Overrides (Pages, Components) ``` Resolution Order: 1. Local components: `src/components/local/` 2. Feature components: `src/components/features/*/` 3. Template components: `src/components/templates/` 4. Framework components: Framework crates ``` **Selection Strategy**: First found wins (no merging for components) ### Route Definitions ``` Resolution Order: 1. Local routes: `config/routes/local/` 2. Feature routes: `config/routes/features/*/` 3. Template routes: `config/routes/templates/` 4. Framework routes: Generated defaults ``` **Merge Strategy**: Route sets are merged with local routes overriding conflicts ### Styling (CSS, UnoCSS) ``` Resolution Order: 1. Local styles: `styles/local/` 2. Feature styles: `styles/features/*/` 3. Template styles: `styles/templates/` 4. Framework styles: Default framework styles ``` **Merge Strategy**: CSS cascade with local styles having highest specificity ## 📁 Directory Structure ``` my-rustelo-project/ ├── config/ │ ├── local/ # Local overrides (highest precedence) │ │ ├── Cargo.toml │ │ ├── justfile │ │ └── app.toml │ ├── features/ # Feature-specific configs │ │ ├── analytics/ │ │ ├── smart-build/ │ │ └── debugging-tools/ │ └── templates/ # Template defaults (lowest precedence) ├── src/ │ ├── components/ │ │ ├── local/ # Local component overrides │ │ ├── features/ # Feature components │ │ └── templates/ # Template components │ └── pages/ │ ├── local/ # Local page overrides │ ├── features/ # Feature pages │ └── templates/ # Template pages ├── routes/ │ ├── local/ # Local route definitions │ ├── features/ # Feature routes │ └── templates/ # Template routes ├── styles/ │ ├── local/ # Local styling │ ├── features/ # Feature styles │ └── templates/ # Template styles └── scripts/ ├── local/ # Local scripts ├── features/ # Feature scripts └── templates/ # Template scripts ``` ## ⚙️ Implementation ### Configuration Resolution Engine ```rust pub struct LayeredConfig { layers: Vec, } #[derive(Debug, Clone)] pub enum ConfigLayer { Local(PathBuf), Feature(String, PathBuf), Template(PathBuf), Framework, } impl LayeredConfig { pub fn resolve(&self, config_name: &str) -> Result where T: DeserializeOwned + Merge { let mut result = T::default(); // Apply layers from lowest to highest precedence for layer in &self.layers { if let Some(config) = self.load_config_from_layer(layer, config_name)? { result.merge(config); } } Ok(result) } } ``` ### Component Resolution Engine ```rust pub struct LayeredComponents { component_dirs: Vec, } #[derive(Debug, Clone)] pub enum ComponentDir { Local(PathBuf), Feature(String, PathBuf), Template(PathBuf), Framework, } impl LayeredComponents { pub fn find_component(&self, name: &str) -> Option { // Search from highest to lowest precedence for dir in &self.component_dirs { if let Some(path) = self.search_component_in_dir(dir, name) { return Some(path); } } None } } ``` ## 🚀 CLI Integration ### Automatic Layer Setup ```bash # Create layered structure when adding features cargo rustelo add analytics # Creates: config/features/analytics/, src/components/features/analytics/, etc. # Create local override cargo rustelo override component Header # Creates: src/components/local/Header.rs (overrides template/feature version) # Create local config override cargo rustelo override config Cargo.toml # Creates: config/local/Cargo.toml (merges with other layers) ``` ### Override Management ```bash # List all overrides cargo rustelo list-overrides # Show override hierarchy for specific item cargo rustelo trace component Header # Output: # Header component resolution: # ✅ src/components/local/Header.rs (USED) # 🔸 src/components/features/analytics/Header.rs # 🔸 src/components/templates/Header.rs # Remove local override (fall back to next layer) cargo rustelo remove-override component Header ``` ## 🛡️ Update Safety ### Framework Updates When running `cargo rustelo update`: 1. **Framework crates** are updated to latest versions 2. **Template defaults** are refreshed (but not applied) 3. **Feature configs** are updated if compatible 4. **Local overrides** are never modified 5. **Conflict detection** warns of incompatibilities ### Feature Updates When running `cargo rustelo add/remove `: 1. **Feature layer** is added/removed 2. **Local overrides** take precedence over new feature configs 3. **Dependency conflicts** are resolved in favor of local choices 4. **Migration warnings** provided for breaking changes ## 🎨 Configuration Merging Examples ### Cargo.toml Merging **Template Layer**: ```toml [dependencies] leptos = "0.6" serde = "1.0" ``` **Feature Layer (analytics)**: ```toml [dependencies] prometheus = "0.13" chrono = "0.4" ``` **Local Layer**: ```toml [dependencies] leptos = "0.7" # Override template version anyhow = "1.0" # Add local dependency ``` **Final Result**: ```toml [dependencies] leptos = "0.7" # Local override serde = "1.0" # From template prometheus = "0.13" # From analytics feature chrono = "0.4" # From analytics feature anyhow = "1.0" # Local addition ``` ### UnoCSS Configuration Merging **Template Layer**: ```typescript export default { theme: { colors: { primary: '#3b82f6', } } } ``` **Feature Layer (analytics)**: ```typescript export default { theme: { colors: { analytics: '#10b981', } }, shortcuts: { 'metric-card': 'bg-white shadow-md rounded-lg p-4', } } ``` **Local Layer**: ```typescript export default { theme: { colors: { primary: '#ef4444', // Override template primary brand: '#8b5cf6', // Add local color } } } ``` **Final Result**: ```typescript export default { theme: { colors: { primary: '#ef4444', // Local override analytics: '#10b981', // From analytics feature brand: '#8b5cf6', // Local addition } }, shortcuts: { 'metric-card': 'bg-white shadow-md rounded-lg p-4', // From analytics } } ``` ## 📋 Benefits ### For Developers - **Full customization** without losing update capability - **Clear precedence** - always know which config wins - **Safe experimentation** - local changes never affect framework - **Easy rollback** - remove local override to revert to defaults ### for Framework Maintainers - **Update safety** - never break user customizations - **Feature composability** - features don't conflict with each other - **Clear boundaries** - framework, template, feature, and local concerns separated - **Debugging support** - trace resolution path for any configuration ### For Teams - **Consistent structure** - all projects follow same layered approach - **Shared overrides** - commit local layer for team-wide customizations - **Feature experimentation** - test features without permanent changes - **Migration safety** - gradual migration between framework versions This layered override system ensures that Rustelo provides maximum flexibility while maintaining the reliability and update safety that production applications require.