# SmartProxy Routing Architecture Unification Plan ## Overview This document analyzes the current state of routing in SmartProxy, identifies redundancies and inconsistencies, and proposes a unified architecture. ## Current State Analysis ### 1. Multiple Route Manager Implementations #### 1.1 Core SharedRouteManager (`ts/core/utils/route-manager.ts`) - **Purpose**: Designed as a shared component for SmartProxy and NetworkProxy - **Features**: - Port mapping and expansion (e.g., `[80, 443]` → individual routes) - Comprehensive route matching (domain, path, IP, headers, TLS) - Route validation and conflict detection - Event emitter for route changes - Detailed logging support - **Status**: Well-designed but underutilized #### 1.2 SmartProxy RouteManager (`ts/proxies/smart-proxy/route-manager.ts`) - **Purpose**: SmartProxy-specific route management - **Issues**: - 95% duplicate code from SharedRouteManager - Only difference is using `ISmartProxyOptions` instead of generic interface - Contains deprecated security methods - Unnecessary code duplication - **Status**: Should be removed in favor of SharedRouteManager #### 1.3 HttpProxy Route Management (`ts/proxies/http-proxy/`) - **Purpose**: HTTP-specific routing - **Implementation**: Minimal, inline route matching - **Status**: Could benefit from SharedRouteManager ### 2. Multiple Router Implementations #### 2.1 ProxyRouter (`ts/routing/router/proxy-router.ts`) - **Purpose**: Legacy compatibility with `IReverseProxyConfig` - **Features**: Domain-based routing with path patterns - **Used by**: HttpProxy for backward compatibility #### 2.2 RouteRouter (`ts/routing/router/route-router.ts`) - **Purpose**: Modern routing with `IRouteConfig` - **Features**: Nearly identical to ProxyRouter - **Issues**: Code duplication with ProxyRouter ### 3. Scattered Route Utilities #### 3.1 Core route-utils (`ts/core/utils/route-utils.ts`) - **Purpose**: Shared matching functions - **Features**: Domain, path, IP, CIDR matching - **Status**: Well-implemented, should be the single source #### 3.2 SmartProxy route-utils (`ts/proxies/smart-proxy/utils/route-utils.ts`) - **Purpose**: Route configuration utilities - **Features**: Different scope - config merging, not pattern matching - **Status**: Keep separate as it serves different purpose ### 4. Other Route-Related Files - `route-patterns.ts`: Constants for route patterns - `route-validators.ts`: Route configuration validation - `route-helpers.ts`: Additional utilities - `route-connection-handler.ts`: Connection routing logic ## Problems Identified ### 1. Code Duplication - **SharedRouteManager vs SmartProxy RouteManager**: ~1000 lines of duplicate code - **ProxyRouter vs RouteRouter**: ~500 lines of duplicate code - **Matching logic**: Implemented in 4+ different places ### 2. Inconsistent Implementations ```typescript // Example: Domain matching appears in multiple places // 1. In route-utils.ts export function matchDomain(pattern: string, hostname: string): boolean // 2. In SmartProxy RouteManager private matchDomain(domain: string, hostname: string): boolean // 3. In ProxyRouter private matchesHostname(configName: string, hostname: string): boolean // 4. In RouteRouter private matchDomain(pattern: string, hostname: string): boolean ``` ### 3. Unclear Separation of Concerns - Route Managers handle both storage AND matching - Routers also handle storage AND matching - No clear boundaries between layers ### 4. Maintenance Burden - Bug fixes need to be applied in multiple places - New features must be implemented multiple times - Testing effort multiplied ## Proposed Unified Architecture ### Layer 1: Core Routing Components ``` ts/core/routing/ ├── types.ts # All route-related types ├── utils.ts # All matching logic (consolidated) ├── route-store.ts # Route storage and indexing └── route-matcher.ts # Route matching engine ``` ### Layer 2: Route Management ``` ts/core/routing/ └── route-manager.ts # Single RouteManager for all proxies - Uses RouteStore for storage - Uses RouteMatcher for matching - Provides high-level API ``` ### Layer 3: HTTP Routing ``` ts/routing/ └── http-router.ts # Single HTTP router implementation - Uses RouteManager for route lookup - Handles HTTP-specific concerns - Legacy adapter built-in ``` ### Layer 4: Proxy Integration ``` ts/proxies/ ├── smart-proxy/ │ └── (uses core RouteManager directly) ├── http-proxy/ │ └── (uses core RouteManager + HttpRouter) └── network-proxy/ └── (uses core RouteManager directly) ``` ## Implementation Plan ### Phase 1: Consolidate Matching Logic (Week 1) 1. **Audit all matching implementations** - Document differences in behavior - Identify the most comprehensive implementation - Create test suite covering all edge cases 2. **Create unified matching module** ```typescript // ts/core/routing/matchers.ts export class DomainMatcher { static match(pattern: string, hostname: string): boolean } export class PathMatcher { static match(pattern: string, path: string): MatchResult } export class IpMatcher { static match(pattern: string, ip: string): boolean static matchCidr(cidr: string, ip: string): boolean } ``` 3. **Update all components to use unified matchers** - Replace local implementations - Ensure backward compatibility - Run comprehensive tests ### Phase 2: Unify Route Managers (Week 2) 1. **Enhance SharedRouteManager** - Add any missing features from SmartProxy RouteManager - Make it truly generic (no proxy-specific dependencies) - Add adapter pattern for different options types 2. **Migrate SmartProxy to use SharedRouteManager** ```typescript // Before this.routeManager = new RouteManager(this.settings); // After this.routeManager = new SharedRouteManager({ logger: this.settings.logger, enableDetailedLogging: this.settings.enableDetailedLogging }); ``` 3. **Remove duplicate RouteManager** - Delete `ts/proxies/smart-proxy/route-manager.ts` - Update all imports - Verify all tests pass ### Phase 3: Consolidate Routers (Week 3) 1. **Create unified HttpRouter** ```typescript export class HttpRouter { constructor(private routeManager: SharedRouteManager) {} // Modern interface route(req: IncomingMessage): RouteResult // Legacy adapter routeLegacy(config: IReverseProxyConfig): RouteResult } ``` 2. **Migrate HttpProxy** - Replace both ProxyRouter and RouteRouter - Use single HttpRouter with appropriate adapter - Maintain backward compatibility 3. **Clean up legacy code** - Mark old interfaces as deprecated - Add migration guides - Plan removal in next major version ### Phase 4: Architecture Cleanup (Week 4) 1. **Reorganize file structure** ``` ts/core/ ├── routing/ │ ├── index.ts │ ├── types.ts │ ├── matchers/ │ │ ├── domain.ts │ │ ├── path.ts │ │ ├── ip.ts │ │ └── index.ts │ ├── route-store.ts │ ├── route-matcher.ts │ └── route-manager.ts └── utils/ └── (remove route-specific utils) ``` 2. **Update documentation** - Architecture diagrams - Migration guides - API documentation 3. **Performance optimization** - Add caching where beneficial - Optimize hot paths - Benchmark before/after ## Migration Strategy ### For SmartProxy RouteManager Users ```typescript // Old way import { RouteManager } from './route-manager.js'; const manager = new RouteManager(options); // New way import { SharedRouteManager as RouteManager } from '../core/utils/route-manager.js'; const manager = new RouteManager({ logger: options.logger, enableDetailedLogging: options.enableDetailedLogging }); ``` ### For Router Users ```typescript // Old way const proxyRouter = new ProxyRouter(); const routeRouter = new RouteRouter(); // New way const router = new HttpRouter(routeManager); // Automatically handles both modern and legacy configs ``` ## Success Metrics 1. **Code Reduction** - Target: Remove ~1,500 lines of duplicate code - Measure: Lines of code before/after 2. **Performance** - Target: No regression in routing performance - Measure: Benchmark route matching operations 3. **Maintainability** - Target: Single implementation for each concept - Measure: Time to implement new features 4. **Test Coverage** - Target: 100% coverage of routing logic - Measure: Coverage reports ## Risks and Mitigations ### Risk 1: Breaking Changes - **Mitigation**: Extensive adapter patterns and backward compatibility layers - **Testing**: Run all existing tests plus new integration tests ### Risk 2: Performance Regression - **Mitigation**: Benchmark critical paths before changes - **Testing**: Load testing with production-like scenarios ### Risk 3: Hidden Dependencies - **Mitigation**: Careful code analysis and dependency mapping - **Testing**: Integration tests across all proxy types ## Long-term Vision ### Future Enhancements 1. **Route Caching**: LRU cache for frequently accessed routes 2. **Route Indexing**: Trie-based indexing for faster domain matching 3. **Route Priorities**: Explicit priority system instead of specificity 4. **Dynamic Routes**: Support for runtime route modifications 5. **Route Templates**: Reusable route configurations ### API Evolution ```typescript // Future unified routing API const routingEngine = new RoutingEngine({ stores: [fileStore, dbStore, dynamicStore], matchers: [domainMatcher, pathMatcher, customMatcher], cache: new LRUCache({ max: 1000 }), indexes: { domain: new TrieIndex(), path: new RadixTree() } }); // Simple, powerful API const route = await routingEngine.findRoute({ domain: 'example.com', path: '/api/v1/users', ip: '192.168.1.1', headers: { 'x-custom': 'value' } }); ``` ## Conclusion The current routing architecture has significant duplication and inconsistencies. By following this unification plan, we can: 1. Reduce code by ~30% 2. Improve maintainability 3. Ensure consistent behavior 4. Enable future enhancements The phased approach minimizes risk while delivering incremental value. Each phase is independently valuable and can be deployed separately.