FERRARI PLATFORM MODULE ALIGNMENT
Documentation for Plans
Ferrari Platform - Module System Alignment
Overview
The Ferrari Platform adapters are designed to work seamlessly with both:
- Editor Monorepo - Using
EditorModuleContractfrom@libs-foundational/core-angular - GoGrab-Space Monorepo - Using
BrowserModuleContractfrom@gograb-space/module-base
Module System Comparison
Editor Monorepo (EditorModuleContract)
Location: libs/core-angular/src/lib/contracts/editor-module-contract.ts
Contract:
export interface EditorModuleContract {
readonly manifest: EditorModuleManifest;
configure(config: ModuleConfig): Observable<void>;
initialize(): Observable<void>;
start(): Observable<void>;
stop(): Observable<void>;
destroy(): Observable<void>;
}
Features:
- Module manifest with navigation, components, actions
- Embeddable components (widgets)
- Public actions
- Module routes
- Dependencies on storage, theme, widgets
- Permissions system
GoGrab-Space Monorepo (BrowserModuleContract)
Location: libs/core/module-base/src/lib/contracts/browser-module.contract.ts
Contract:
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>;
}
Features:
- Module manifest with metadata
- Angular routes
- Embeddable components for cross-module UI
- Public actions for cross-module execution
@ModuleDecoratorfor metadata- Log system integration
- Multi-tenant support
Ferrari Platform Adapter Compatibility
LibraryModuleAdapter
The base LibraryModuleAdapter in the Ferrari Platform implements a minimal contract that's compatible with both systems:
export interface BrowserModuleContract {
readonly manifest: ModuleManifest;
configure<T = Record<string, unknown>>(config: T): Observable<void>;
initialize(): Observable<void>;
start(): Observable<void>;
stop(): Observable<void>;
destroy(): Observable<void>;
}
This allows the adapters to work with:
- ✅ Editor modules using
EditorModuleContract - ✅ GoGrab-Space modules using
BrowserModuleContract - ✅ Custom modules implementing either contract
Fixed Issues
User Management Module (Editor Repo)
Problem: Import from wrong package
// ❌ WRONG
import { EditorModuleContract } from '@libs-foundational/core-models';
// ✅ CORRECT
import { EditorModuleContract } from '@libs-foundational/core-angular';
Files Fixed:
libs/modules/user-management/src/lib/user-management.module.tslibs/modules/user-management/src/lib/user-management.manifest.tslibs/core-angular/src/index.ts(added contract export)
Module Contract Alignment
Both contracts share the same lifecycle pattern:
- configure() - Set up dependencies
- initialize() - Load data, setup state
- start() - Activate services
- stop() - Deactivate services
- destroy() - Clean up resources
Module Configuration Comparison
Editor Repo Configuration
interface ModuleConfig {
storage?: any; // Storage system instance
theme?: any; // Theme system instance
widgets?: any; // Widget generator instance
custom?: Record<string, any>;
}
GoGrab-Space Configuration
// Passed via generic type parameter
configure<T = Record<string, unknown>>(config: T): Observable<void>
Recent GoGrab-Space Changes (Commit 69bd22f)
Key Updates
- Module Config Mock API - Enhanced with proper tenant handling
- Dashboard Builder - Improved widget resolution
- App Config Service - Better configuration management
- Component Registry - Simplified registration
Alignment Actions Taken
- ✅ Fixed import errors in editor repo
- ✅ Exported
EditorModuleContractfrom@libs-foundational/core-angular - ✅ Verified Ferrari Platform adapter compatibility
- ✅ Documented both module systems
Best Practices
Creating Modules for Editor Repo
import {
EditorModuleContract,
EditorModuleManifest,
ModuleConfig,
Module
} from '@libs-foundational/core-angular';
@Module({ manifest: MY_MODULE_MANIFEST })
@Injectable({ providedIn: 'root' })
export class MyModule implements EditorModuleContract {
readonly manifest = MY_MODULE_MANIFEST;
configure(config: ModuleConfig): Observable<void> {
// Use config.storage, config.theme, config.widgets
return of(void 0);
}
// ... lifecycle methods
}
Creating Modules for GoGrab-Space Repo
import {
BrowserModuleContract,
ModuleManifest,
ModuleDecorator,
} from '@gograb-space/module-base';
import { LoggerService } from '@gograb-space/log-system';
@ModuleDecorator({
id: 'my-module',
version: '1.0.0',
permissions: [/* ... */],
navigation: {/* ... */}
})
@Injectable({ providedIn: 'root' })
export class MyModule implements BrowserModuleContract {
private readonly logger = inject(LoggerService);
readonly manifest: ModuleManifest = { /* ... */ };
configure<T = Record<string, unknown>>(config: T): Observable<void> {
this.logger.info('Configuring module...');
return of(void 0);
}
// ... lifecycle methods
}
Ferrari Platform Integration
Using Adapters with Editor Modules
import { AdapterLoaderService, SpaceMapAdapter } from '@module-adapter';
import { UserManagementModule } from '@user-management';
// Load Ferrari adapters
this.loader.loadAdapters([
inject(SpaceMapAdapter),
inject(EditorWebAdapter),
inject(SingularityAdapter),
inject(UIBuilderAdapter)
], { autoInitialize: true });
// Load editor modules
const userModule = inject(UserManagementModule);
await firstValueFrom(userModule.configure({
storage: storageService,
theme: themeService
}));
await firstValueFrom(userModule.initialize());
Using Adapters with GoGrab-Space Modules
import { AdapterLoaderService } from '@module-adapter';
import { UserManagementModule } from '@gograb-space/user-management';
// Load Ferrari adapters (same API)
this.loader.loadAdapters([
inject(SpaceMapAdapter),
// ... other adapters
], { autoInitialize: true });
// GoGrab-Space modules work the same way
const userModule = inject(UserManagementModule);
await firstValueFrom(userModule.configure({}));
await firstValueFrom(userModule.initialize());
Key Differences
| Feature | Editor Repo | GoGrab-Space Repo |
|---|---|---|
| Contract Name | EditorModuleContract |
BrowserModuleContract |
| Package | @libs-foundational/core-angular |
@gograb-space/module-base |
| Decorator | @Module |
@ModuleDecorator |
| Logger | Optional | Required (LoggerService) |
| Config Type | ModuleConfig |
Generic <T> |
| Storage | config.storage | Inject separately |
| Theme | config.theme | Inject separately |
State Management
Editor Repo
- Uses Flash Persistence from
@storage-system - Zero NGXS dependencies in new code
- Signal-based state
GoGrab-Space Repo
- Uses Flash Persistence (NGXS replacement)
- Modern signal-based reactivity
- Multi-tenant state isolation
Both systems are aligned on using Flash Persistence! ✅
Conclusion
The Ferrari Platform adapters are fully compatible with both module systems. The fixes applied ensure:
- ✅ No import errors
- ✅ Proper exports from
@libs-foundational/core-angular - ✅ Compatible lifecycle patterns
- ✅ Aligned state management (Flash Persistence)
- ✅ Cross-monorepo module support
The platform can seamlessly integrate modules from both the editor and gograb-space monorepos without modification.
Last Updated: October 23, 2025
Status: ✅ Fully Aligned