Module System Architecture
Why we use BrowserModuleContract and hybrid routing strategy
Module System Architecture
Decision Date: November 1, 2025
Decision Owner: Platform Team
Status: Approved - Implementation in Progress
Executive Summary
Decision: Use BrowserModuleContract from @libs-core/module-base as the single, unified module system across the entire platform.
Replace: EditorModuleContract from @libs-foundational/core-angular
Approach: Hybrid routing - Static routes for platform tools, dynamic routes for user-created modules.
The Decision: Hybrid Approach + BrowserModuleContract
Platform Tools (Static Routes)
- Tools: Editor, Space Map, Singularity, Modularity, Launch Station
- Routes: Defined in
apps/gograb-space/src/app/app.routes.ts - Manifests: Provided for AI training but not used for dynamic routing
- Registration: Not dynamically registered
User Modules (Dynamic Routes)
- Created: Via Modularity tool by users
- Contract: Implement BrowserModuleContract
- Routes: Registered at runtime via DynamicRouteService
- Self-Contained: Fully independent modules
Why BrowserModuleContract?
1. Maturity and Feature Completeness
BrowserModuleContract (from gograb-space monorepo):
- ✅ Unified Parameter System with
ModuleParameterMetadata - ✅ Rich validation with customizable error messages
- ✅ UI hints for automatic form generation
- ✅ Fluent builder API (
ModuleParameterBuilder) - ✅ Pre-configured builders for common cases
- ✅ Parameter analysis and introspection
- ✅ Generic validation service
- ✅ Fully immutable (
readonlyproperties)
EditorModuleContract (from editor monorepo):
- ❌ Simple input/output schemas (no rich metadata)
- ❌ Basic parameter system
- ❌ No UI generation hints
- ❌ No fluent builder API
- ❌ Limited validation capabilities
2. AI Training Simplification
Single Pattern:
- AI learns ONE contract pattern (BrowserModuleContract)
- All modules follow same structure
- Consistent parameter definitions
- Easier to train, easier to generate
Multiple Patterns (Current):
- AI must learn two different systems
- Risk of confusion and incorrect generation
- Maintenance overhead
3. Type Safety
BrowserModuleContract:
export interface BrowserModuleContract {
readonly manifest: ModuleManifest;
readonly routes?: Routes;
readonly embeddableComponents?: EmbeddableComponent[];
readonly publicActions?: ModuleAction[];
configure<T = Record<string, unknown>>(config: T): Observable<void>;
initialize(): Observable<void>;
start(): Observable<void>;
stop(): Observable<void>;
destroy(): Observable<void>;
}
EditorModuleContract:
export interface EditorModuleContract {
readonly manifest: EditorModuleManifest;
configure(config: ModuleConfig): Observable<void>;
initialize(): Observable<void>;
start(): Observable<void>;
stop(): Observable<void>;
destroy(): Observable<void>;
}
Advantages:
- Better TypeScript support with generic config type
- More explicit about component and action exports
- Clearer separation of concerns
4. Ecosystem Alignment
- Gograb-Space monorepo already uses BrowserModuleContract
- Two teams: Editor team can learn from gograb-space team
- Cross-pollination: Patterns and best practices shared
- Future merger: Easier if both use same system
Alternatives Considered
Alternative 1: Keep Both Systems
Pros:
- No migration needed
- Existing code continues to work
Cons:
- Two systems to maintain
- Confusion for AI training
- Inconsistent patterns
- Tech debt accumulates
Verdict: ❌ Rejected - Tech debt too high
Alternative 2: Create New Unified System
Pros:
- Could be better than both
- Clean slate design
Cons:
- Time-consuming (2-3 weeks)
- Risk of new bugs
- Delays production timeline
- Two migrations needed (from both old systems)
Verdict: ❌ Rejected - Too time-consuming
Alternative 3: Use EditorModuleContract Everywhere
Pros:
- Already in editor monorepo
- No need to copy code
Cons:
- Less feature-complete
- No unified parameter system
- Gograb-space team would need to migrate
- Moving backward, not forward
Verdict: ❌ Rejected - Less capable
Alternative 4: Hybrid with BrowserModuleContract (CHOSEN)
Pros:
- ✅ Best of both worlds
- ✅ More mature system
- ✅ Unified parameter system
- ✅ AI training simplification
- ✅ Future-proof
- ✅ Ecosystem alignment
Cons:
- Migration needed for user-management module
- Need to copy module-base from gograb-space
Verdict: ✅ SELECTED - Best long-term solution
Migration Strategy
Phase 1: Copy Infrastructure
# Copy module-base from gograb-space to editor monorepo
# Already exists at: libs/core/module-base
Status: ✅ Complete (module-base already exists)
Phase 2: Update User Management Module
File: modules/user-management/src/lib/user-management.module.ts
Changes:
Replace import:
// OLD import { EditorModuleContract, Module } from '@libs-foundational/core-angular'; // NEW import { BrowserModuleContract, ModuleDecorator } from '@libs-core/module-base';Replace decorator:
// OLD @Module({ manifest: USER_MODULE_MANIFEST }) // NEW @ModuleDecorator({ id: 'user-management', version: '1.0.0', name: 'User Management' })Implement new contract:
// OLD export class UserManagementModule implements EditorModuleContract // NEW export class UserManagementModule implements BrowserModuleContractAdd rich parameters to manifest:
publicActions: [ { id: 'users:create', displayName: 'Create User', parameters: [ ModuleParameterBuilder.string('name') .required('Name is required') .minLength(2) .maxLength(100) .build(), ModuleParameterBuilder.email('email') .required('Email is required') .build() ], handler: (params) => of(this.createUser(params)) } ]
Status: ⏳ Pending
Phase 3: Remove EditorModuleContract
Files to Update:
libs/core-angular/src/lib/contracts/editor-module-contract.ts- DELETElibs/core-angular/src/index.ts- Remove exportlibs/core-angular/src/lib/services/editor-module-integrator.service.ts- UPDATE or REMOVE
Status: ⏳ Pending
Phase 4: Update Documentation
Files to Update:
modules/README.md- Update referencesmodules/index.md- Update references- Any other docs mentioning EditorModuleContract
Status: ⏳ Pending
Implementation Impact
Files Affected
- To Modify: 1 module (user-management)
- To Remove: 1 interface (EditorModuleContract)
- To Update: 1 service (editor-module-integrator or remove)
- To Update: ~3-5 documentation files
Estimated Effort
- Migration: 2-3 hours
- Testing: 1-2 hours
- Documentation: 1 hour
- Total: 4-6 hours
Risk Assessment
Risk Level: Medium
Risks:
- Module registration may break - Mitigation: Test thoroughly
- Integration service may need rewrite - Mitigation: May not be needed with new approach
- Hidden dependencies - Mitigation: Run comprehensive tests
Routing Strategy
Building Mode (Platform Builders)
URL Pattern: /:spaceSlug/tool
/:spaceSlug/dashboard
/:spaceSlug/editor
/:spaceSlug/space-map
/:spaceSlug/singularity
/:spaceSlug/modularity
/:spaceSlug/launch-station
/:spaceSlug/ui-builder
Characteristics:
- Static routes in
app.routes.ts - Space context from URL parameter
- Navigation between tools preserves space
- Manifests exist but not used for dynamic routing
Deployed Mode (End Users)
URL Pattern: subdomain.gograb.space/route
myUniverse.gograb.space/
myUniverse.gograb.space/about
myUniverse.gograb.space/products
myUniverse.gograb.space/contact
Characteristics:
- Routes from deployed module manifest
- No space slug in URL
- Universe determined from subdomain
- Clean, production URLs
User Module Routes (Dynamic)
Registration: Runtime via DynamicRouteService
// Module manifest defines routes
const manifest: ModuleManifest = {
routes: [
{
path: 'users',
loadComponent: () => import('./user-list.component')
},
{
path: 'users/:id',
loadComponent: () => import('./user-detail.component')
}
]
};
// Routes registered when module deployed
await dynamicRouteService.registerModuleRoutes(manifest);
Benefits of This Architecture
1. Simplicity
- ✅ ONE module contract to learn
- ✅ Clear separation: Static vs Dynamic
- ✅ Predictable behavior
2. Flexibility
- ✅ Platform tools stable (static)
- ✅ User modules extensible (dynamic)
- ✅ Easy to add new tools or modules
3. Maintainability
- ✅ Single system to maintain
- ✅ Clear patterns to follow
- ✅ Easy to onboard new developers
4. AI-Friendly
- ✅ One contract pattern to train
- ✅ Consistent parameter definitions
- ✅ Clear examples for AI to learn from
5. Production-Ready
- ✅ Proven in gograb-space monorepo
- ✅ Battle-tested patterns
- ✅ Scalable architecture
Verification Checklist
After migration:
Build Verification
- User management module compiles
- No TypeScript errors
- No linter errors
- App builds successfully
Runtime Verification
- User management module loads
- Module actions work
- Module routes work
- No console errors
Documentation Verification
- All docs updated
- No references to EditorModuleContract
- Examples use BrowserModuleContract
- Architecture docs complete
Future Considerations
Phase 2: Module Generator
Once BrowserModuleContract is established:
- Modularity tool generates modules using this contract
- AI trained on BrowserModuleContract examples
- Template modules all use this pattern
Phase 5: AI Training
With single contract:
- Create training dataset of module examples
- Train AI to generate complete modules
- AI understands ModuleParameterMetadata
- AI can generate valid module manifests
Phase 6: Subdomain Deployment
With clear routing:
- Launch Station uses module manifests
- Generates routes for deployed universes
- Clean URLs for end users
Documentation Links
Related Documents:
- Phase 0 Cleanup - Current implementation phase
- Routing Architecture - Detailed routing strategy
- Deprecated Removal Checklist - What's being removed
Code References:
- BrowserModuleContract:
libs/core/module-base/src/lib/contracts/browser-module.contract.ts - EditorModuleContract:
libs/core-angular/src/lib/contracts/editor-module-contract.ts(to be removed) - User Management:
modules/user-management/src/lib/user-management.module.ts(to be updated)
Decision Status: ✅ Approved
Implementation Status: 🎯 In Progress
Expected Completion: Week 1 (November 8, 2025)
Owner: Platform Team