Universal Module Architecture - Integration & Testing Guide

Complete guide for integrating tools and testing the new architecture

๐Ÿงช Universal Module Architecture - Integration & Testing Guide

For: Next implementation session
Focus: Tool integration and comprehensive testing
Goal: Complete the transformation and ensure quality


๐Ÿ”ง Tool Integration

1. Editor Integration

Current State: Editor manages pages independently
Goal: Editor creates and manages page modules

Changes Needed

File: libs/editor-ui/src/lib/services/editor.service.ts

// Before:
saveToGalaxy(pageData: PageData): Observable<Page>

// After:
saveAsModule(pageData: PageData): Observable<UniversalModule> {
  return this.universalModuleService.createPage(
    this.currentUniverseId(),
    pageData.title,
    pageData.route,
    pageData.parentId // Can be galaxy or world module
  );
}

Integration Points:

  1. Replace page creation with module creation
  2. Update page list to query modules with type='page'
  3. Add parent module selector
  4. Update save/load to use module storage

2. Singularity Integration

Current State: Singularity manages flows independently
Goal: Flows attach to any module type

Changes Needed

File: libs/singularity-lib/src/lib/services/singularity.service.ts

// Add module attachment
attachFlowToModule(flowId: string, moduleId: string): Observable<void> {
  return this.universalModuleService.update(moduleId, {
    flows: [...(module.flows || []), flowId]
  });
}

// Query flows by module
getModuleFlows(moduleId: string): Observable<Flow[]> {
  return this.universalModuleService.query({ id: moduleId }).pipe(
    switchMap(modules => {
      const module = modules[0];
      return this.getFlowsByIds(module.flows || []);
    })
  );
}

3. Modularity Integration

Current State: Modularity packages pages and flows
Goal: Modularity packages any module combination

Changes Needed

File: libs/modularity-lib/src/lib/services/module-packager.service.ts

// Package any modules
packageModules(moduleIds: string[]): Observable<PackagedModule> {
  return this.universalModuleService.query({
    id: { $in: moduleIds }
  }).pipe(
    map(modules => this.createPackage(modules))
  );
}

// Install packaged modules
installPackage(package: PackagedModule, targetUniverseId: string): Observable<void> {
  return from(package.modules).pipe(
    concatMap(module => 
      this.universalModuleService.install(targetUniverseId, module)
    )
  );
}

4. Launch Station Integration

Current State: Launch Station shows universes
Goal: Launch Station deploys module-based universes

Changes Needed

File: libs/launch-station-lib/src/lib/services/deployment.service.ts

// Get deployable structure
getDeployableStructure(universeId: string): Observable<DeploymentManifest> {
  return this.universalModuleService.getModuleTree(universeId).pipe(
    map(tree => this.buildDeploymentManifest(tree))
  );
}

// Build manifest from modules
private buildDeploymentManifest(tree: ModuleTreeNode[]): DeploymentManifest {
  return {
    routes: this.moduleRouterService.generateRoutes(
      this.flattenTree(tree)
    ),
    components: this.extractComponents(tree),
    assets: this.extractAssets(tree)
  };
}

๐Ÿงช Testing Strategy

Unit Tests

Test 1: Type System

File: libs/core-models/src/lib/types/universal-module.types.spec.ts

describe('Universal Module Types', () => {
  describe('MODULE_TYPE_REGISTRY', () => {
    it('should have metadata for all module types', () => {
      const types: ModuleType[] = [
        'galaxy', 'world', 'page', 
        'navigation', 'feature', 'widget',
        'layout', 'data', 'flow', 'custom'
      ];
      
      types.forEach(type => {
        expect(MODULE_TYPE_REGISTRY[type]).toBeDefined();
        expect(MODULE_TYPE_REGISTRY[type].label).toBeTruthy();
      });
    });
    
    it('should preserve cosmic terms', () => {
      expect(MODULE_TYPE_REGISTRY.galaxy.cosmicTerm).toBe('Galaxy');
      expect(MODULE_TYPE_REGISTRY.world.cosmicTerm).toBe('World');
      expect(MODULE_TYPE_REGISTRY.page.cosmicTerm).toBe('Page');
    });
  });
  
  describe('Helper Functions', () => {
    it('should check if module can have children', () => {
      expect(canModuleTypeHaveChildren('galaxy')).toBe(true);
      expect(canModuleTypeHaveChildren('world')).toBe(true);
      expect(canModuleTypeHaveChildren('page')).toBe(false);
    });
  });
});

Test 2: Universal Module Service

File: libs/core-angular/src/lib/services/universal-module.service.spec.ts

describe('UniversalModuleService', () => {
  let service: UniversalModuleService;
  let storage: GgStorage;
  
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [UniversalModuleService, GgStorage]
    });
    service = TestBed.inject(UniversalModuleService);
    storage = TestBed.inject(GgStorage);
  });
  
  describe('install', () => {
    it('should create a galaxy module', (done) => {
      service.createGalaxy(
        'universe-1',
        'Products',
        '/products'
      ).subscribe(module => {
        expect(module.type).toBe('galaxy');
        expect(module.name).toBe('Products');
        expect(module.route).toBe('/products');
        done();
      });
    });
    
    it('should create nested modules', (done) => {
      // Create galaxy
      service.createGalaxy('universe-1', 'Products', '/products')
        .pipe(
          switchMap(galaxy => 
            // Create world inside galaxy
            service.createWorld(
              'universe-1',
              'Electronics',
              '/electronics',
              galaxy.id
            )
          )
        )
        .subscribe(world => {
          expect(world.type).toBe('world');
          expect(world.parentId).toBeDefined();
          done();
        });
    });
  });
  
  describe('query', () => {
    it('should filter by type', (done) => {
      service.query({ type: 'galaxy' }).subscribe(modules => {
        modules.forEach(m => expect(m.type).toBe('galaxy'));
        done();
      });
    });
    
    it('should filter by parent', (done) => {
      service.query({ parentId: 'galaxy-1' }).subscribe(modules => {
        modules.forEach(m => expect(m.parentId).toBe('galaxy-1'));
        done();
      });
    });
  });
  
  describe('buildModuleTree', () => {
    it('should build correct hierarchy', () => {
      const modules: UniversalModule[] = [
        { id: '1', type: 'galaxy', name: 'G1', parentId: undefined },
        { id: '2', type: 'world', name: 'W1', parentId: '1' },
        { id: '3', type: 'page', name: 'P1', parentId: '2' }
      ];
      
      const tree = service.buildModuleTree(modules);
      
      expect(tree.length).toBe(1); // One root
      expect(tree[0].module.id).toBe('1');
      expect(tree[0].children.length).toBe(1);
      expect(tree[0].children[0].children.length).toBe(1);
    });
  });
});

Test 3: Module Migration

File: libs/universe-map/src/lib/services/module-migration.service.spec.ts

describe('ModuleMigrationService', () => {
  let service: ModuleMigrationService;
  
  describe('convertGalaxyToModule', () => {
    it('should convert galaxy to module with type=galaxy', () => {
      const galaxy = {
        id: 'old-galaxy-1',
        name: 'Products',
        route: '/products',
        universeId: 'universe-1'
      };
      
      const module = service['convertGalaxyToModule'](galaxy, 'universe-1');
      
      expect(module.type).toBe('galaxy');
      expect(module.name).toBe('Products');
      expect(module.route).toBe('/products');
      expect(module.config.originalId).toBe('old-galaxy-1');
    });
  });
  
  describe('migrateUniverse', () => {
    it('should migrate complete structure', (done) => {
      service.migrateUniverse('universe-1', 'space-1')
        .subscribe(result => {
          expect(result.success).toBe(true);
          expect(result.migratedModules).toBeGreaterThan(0);
          expect(result.errors.length).toBe(0);
          done();
        });
    });
  });
});

Integration Tests

Test 1: End-to-End Module Creation

describe('Module Creation E2E', () => {
  it('should create complete universe structure', async () => {
    // 1. Create galaxy
    const galaxy = await moduleService.createGalaxy(
      'universe-1',
      'Products',
      '/products'
    ).toPromise();
    
    // 2. Create world in galaxy
    const world = await moduleService.createWorld(
      'universe-1',
      'Electronics',
      '/electronics',
      galaxy.id
    ).toPromise();
    
    // 3. Create page in world
    const page = await moduleService.createPage(
      'universe-1',
      'Laptops',
      '/laptops',
      world.id
    ).toPromise();
    
    // 4. Verify tree structure
    const tree = await moduleService.getModuleTree('universe-1').toPromise();
    expect(tree.length).toBe(1); // One root (galaxy)
    expect(tree[0].children.length).toBe(1); // One world
    expect(tree[0].children[0].children.length).toBe(1); // One page
  });
});

Test 2: Tool Integration

describe('Editor Integration', () => {
  it('should save editor page as module', async () => {
    const page = await editorService.savePage({
      title: 'My Page',
      widgets: [widget1, widget2]
    }).toPromise();
    
    // Verify it's a module
    const modules = await moduleService.query({
      type: 'page',
      name: 'My Page'
    }).toPromise();
    
    expect(modules.length).toBe(1);
    expect(modules[0].type).toBe('page');
    expect(modules[0].widgets).toEqual([widget1, widget2]);
  });
});

E2E Tests

Test 1: Complete User Journey

describe('Space-Builder Journey', () => {
  it('should complete full platform creation workflow', async () => {
    // 1. Create universe
    const universe = await spaceService.createUniverse({
      name: 'My Store'
    });
    
    // 2. Create structure via Universe Map
    await navigateTo(`/space/${spaceId}/universe-map`);
    
    // 3. Create galaxy
    await click('[data-test="create-galaxy"]');
    await fillForm({ name: 'Products', route: '/products' });
    await click('[data-test="create"]');
    
    // 4. Create world in galaxy
    await selectModule('Products');
    await click('[data-test="create-child"]');
    await selectType('world');
    await fillForm({ name: 'Electronics', route: '/electronics' });
    await click('[data-test="create"]');
    
    // 5. Create page in Editor
    await navigateTo(`/space/${spaceId}/editor`);
    await click('[data-test="new-page"]');
    await fillForm({ title: 'Laptops' });
    await selectParent('Electronics');
    await click('[data-test="save"]');
    
    // 6. Verify structure
    const tree = await moduleService.getModuleTree(universe.id);
    expect(tree).toHaveStructure({
      galaxy: 'Products',
      children: [{
        world: 'Electronics',
        children: [{
          page: 'Laptops'
        }]
      }]
    });
    
    // 7. Deploy
    await navigateTo(`/space/${spaceId}/launch-station`);
    await selectUniverse('My Store');
    await click('[data-test="deploy"]');
    
    // 8. Verify deployment
    expect(deployment.status).toBe('success');
    expect(deployment.url).toContain('my-store');
  });
});

๐ŸŽฏ Integration Checklist

Core Services โœ…

Libraries

Components

Routes

Data


๐Ÿ“Š Testing Coverage Goals

Unit Tests Target: >90%

Services (Target: 95%):

Components (Target: 85%):

Types (Target: 100%):

Integration Tests Target: 80%

Module Operations:

Tool Integration:

E2E Tests Target: 70%

Critical Paths:


๐Ÿ”„ Migration Testing

Test Scenarios

Scenario 1: Simple Universe

Before:
- Universe "Blog"
- Galaxy "Posts"
- Pages [Home, About, Contact]

After:
- Universe "Blog"
- Galaxy Module (type='galaxy', name='Posts')
- Page Modules (type='page', names=['Home', 'About', 'Contact'])

Verify:
โœ“ All entities converted
โœ“ Relationships preserved
โœ“ No data lost

Scenario 2: Complex Universe

Before:
- Universe "Store"
- Galaxy "Products"
  - World "Electronics"
    - Pages [Laptops, Phones]
  - World "Clothing"
    - Pages [Shirts, Pants]

After:
- Universe "Store"
- Galaxy Module "Products"
  - World Module "Electronics"
    - Page Modules [Laptops, Phones]
  - World Module "Clothing"
    - Page Modules [Shirts, Pants]

Verify:
โœ“ Full hierarchy preserved
โœ“ All parent-child relationships intact
โœ“ Routes generated correctly

๐Ÿš€ Performance Testing

Benchmarks

Module Operations (Target: <10ms):

Tree Operations (Target: <50ms):

Storage Operations (Target: <50ms):


โœ… Quality Gates

Code Quality

Functionality

Performance

User Experience


๐Ÿ“‹ Final Acceptance Criteria

Must Have โœ…

  1. โœ… UniversalModuleService working
  2. โœ… All module types supported
  3. โœ… Tree operations functional
  4. โœ… Components render correctly
  5. โœ… Routes integrate with app
  6. โœ… Migration system ready

Should Have

  1. Editor integration complete
  2. Tool integration complete
  3. Unit tests >90%
  4. Integration tests pass
  5. Performance benchmarks met

Nice to Have

  1. E2E tests complete
  2. Advanced features (drag-drop, etc.)
  3. AI generation tested
  4. Production deployment guide

๐ŸŽฏ Next Steps

Immediate (Next Session)

  1. Complete tool integration (8-10 hours)
  2. Write comprehensive tests (8-10 hours)
  3. Test migration with real data (4-6 hours)
  4. Polish UI/UX (4-6 hours)

Short Term (Week 2-3)

  1. Production migration
  2. Performance optimization
  3. Documentation completion
  4. User training materials

Medium Term (Week 4-5)

  1. Advanced features
  2. AI enhancements
  3. Marketplace integration
  4. Analytics integration

Status: ๐ŸŽฏ READY FOR INTEGRATION PHASE
Test Coverage Target: >90%
Quality Level: PRODUCTION GRADE


This testing strategy ensures the Universal Module Architecture is robust, reliable, and ready for production! ๐Ÿš€