# Service Center vs Legacy Services Hub — Comparison & Assessment ## Executive Summary The **Service Center** (`modules/serviceCenter`) is a superior architecture compared to the legacy **Services Hub** (`modules/services`). It was worthwhile to create it. The main benefits are: **explicit dependency graph**, **lazy loading**, **per-service RBAC**, and **context-scoped resolution** without carrying the entire hub. The legacy hub remains valid for incremental migration and backward compatibility. --- ## 1. Architecture Comparison | Aspect | Service Center | Legacy Services Hub | |--------|----------------|---------------------| | **Location** | `modules/serviceCenter/` | `modules/services/` | | **Entry point** | `getService(key, context, legacy_hub)` | `getInterface(user, ...)` → `Services` | | **Constructor** | `(context, get_service)` | `(services)` — full hub | | **Dependencies** | Declared in registry, resolved lazily via `get_service("key")` | Via `self.services.` — all services always present | | **Loading** | **Lazy** — only requested services + deps | **Eager** — everything at construction | | **RBAC** | Per-service `objectKey`, `can_access_service()` | Shared via hub `.rbac` | | **Caching** | Per-context cache (user + mandate + featureInstance) | No instance cache — new `Services` each call | | **Feature override** | N/A — features use `getService` directly | Feature services override hub attributes | | **Pre-warm** | `preWarm()` at app startup | None | | **Structure** | Core vs importable split; explicit registry | Flat `serviceX/` dirs; discovery via glob | --- ## 2. Which Setup is Better? **Service Center is better** for these reasons: ### 2.1 Explicit Dependency Graph - Dependencies are declared in `registry.py` (e.g. `"ai": {"dependencies": ["chat", "utils", "extraction", "billing"]}`). - Circular dependencies are detected and raise `RuntimeError`. - Easier to reason about and refactor. ### 2.2 Lazy Loading & Resource Efficiency - Only requested services (and their transitive deps) are loaded. - A feature like chatbot needs `chat`, `ai`, `billing`, `streaming` — not `sharepoint`, `ticket`, `neutralization`, etc. - Legacy hub loads **everything** on first `getInterface()`. ### 2.3 Context-Scoped Resolution - Each request gets a `ServiceCenterContext` (user, mandate_id, feature_instance_id, workflow). - Resolution is cached per context. Same user+mandate+feature → same instances. - No need to pass or construct a full hub. ### 2.4 Per-Service RBAC - Services have `objectKey` (e.g. `service.ai`, `service.extraction`). - `can_access_service(user, rbac, service_key)` checks before resolving. - Finer-grained control than a single hub-level RBAC. ### 2.5 Separation of Concerns - **Core services** (utils, security, streaming): internal, no RBAC. - **Importable services** (ai, billing, extraction, etc.): feature-facing, RBAC-protected. - Clear distinction vs. flat structure in legacy. ### 2.6 Pre-warm for Cold Start - `preWarm()` imports all service modules at startup. - First request avoids import latency. - Legacy has no equivalent. --- ## 3. When Legacy Still Makes Sense - **Migration**: Features that haven’t moved yet still use `getInterface()`. - **Feature overrides**: Feature-specific services (e.g. `serviceAi/mainServiceAi.py` in a feature) that override hub attributes. - **Backward compatibility**: `legacy_hub` fallback in Service Center allows gradual migration. --- ## 4. Did It Make Sense to Create the Service Center? **Yes.** The legacy hub has inherent limitations: 1. **Monolithic hub** — every `getInterface()` constructs a full `Services` object with all services, interfaces, and feature discovery. 2. **Implicit dependencies** — services grab what they need via `self.services.`, leading to hidden coupling. 3. **No explicit RBAC per service** — access control is at the hub level. 4. **Eager loading** — every request pays for all services even when only a few are used. Service Center addresses these while keeping a migration path via `legacy_hub` fallback. The Chatbot feature already uses it successfully. --- ## 5. Benchmark Script Run the comparison script to measure runtime and memory: ```bash # From gateway root python tests/benchmarks/benchmark_service_center_vs_legacy.py ``` See `tests/benchmarks/benchmark_service_center_vs_legacy.py` for details on metrics and methodology.