MODULE GENERATION ARCHITECTURE

Documentation for Architecture

Module Generation Architecture — Complete Knowledge Base

Last updated: 2026-02-23 (Session 138.8) Source: Testing sessions S137–S138.8, MongoDB Atlas analysis, codebase tracing

This document captures everything learned about the platform's module generation pipeline, data persistence, and JSON-to-Angular rendering system. It should be treated as the definitive reference for anyone working on the generation flow.


Table of Contents

  1. Pipeline Overview
  2. The 7 Phases in Detail
  3. SSE Streaming & Frontend Communication
  4. Database Persistence Architecture
  5. JSON-to-Angular: How Modules Become UI
  6. Document Schemas (Full Reference)
  7. Key IDs & Mappings
  8. File Locations (Codebase Map)
  9. Configuration & Defaults
  10. Known Bugs & Their Root Causes
  11. Performance Data
  12. Process Persistence (Session Recovery)
  13. Deploy to Universe Flow
  14. Testing Checklist

1. Pipeline Overview

Pipeline B (backend-vitto-api/module-generation/) is the ACTIVE generation pipeline. It is triggered from the Vibe Universe Builder UI at:

http://localhost:6200/space/{spaceId}/universe/{universeId}/vibe

The pipeline runs on backend-vitto-api (port 3003) and communicates with the frontend via Server-Sent Events (SSE).

Architecture Diagram

┌──────────────────────┐     SSE Stream      ┌──────────────────────┐
│  Frontend (Angular)  │ ◄──────────────────  │  backend-vitto-api   │
│  Port 6200           │                      │  Port 3003           │
│                      │  GET /start?params   │                      │
│  vibe-universe-      │ ──────────────────►  │  module-generation/  │
│  generator.component │                      │  controller.ts       │
│                      │                      │                      │
│  workflow-state.     │                      │  module-gen-phase.   │
│  service.ts          │                      │  executor.ts         │
└──────────┬───────────┘                      └──────────┬───────────┘
           │                                             │
           │ POST /spaces/:id/modules                    │ POST /ai-api/modules
           ▼                                             ▼
┌──────────────────────┐                      ┌──────────────────────┐
│  backend-api         │                      │  backend-ai-api      │
│  Port 3000           │                      │  Port 3001           │
│                      │                      │                      │
│  space_modules       │                      │  generated-modules   │
│  (GoGrabSpace DB)    │                      │  (ai-agents DB)      │
└──────────────────────┘                      └──────────────────────┘

Entrypoints

What URL Method
Start generation /vitto-api/module-generation/start GET (SSE)
Reconnect to stream /vitto-api/module-generation/stream/:sessionId GET (SSE)
Check status /vitto-api/module-generation/status/:sessionId GET
Resume from checkpoint /vitto-api/module-generation/resume/:sessionId POST

2. The 7 Phases in Detail

Each phase is implemented as a separate class in apis/backend-vitto-api/src/app/module-generation/phases/.

Phase 1: ENHANCE

Phase 2: ANALYZE

Phase 3: DECOMPOSE

Phase 4: PLAN

Phase 5: EXECUTE (Most Complex)

Phase 6: INTEGRATE

Phase 7: DEPLOY


3. SSE Streaming & Frontend Communication

SSE Event Types

The pipeline emits ModuleGenSSEEvent objects through Server-Sent Events:

interface ModuleGenSSEEvent {
  type: 'phase-started' | 'phase-completed' | 'progress' | 'module-gen.completed' | 'error';
  phase?: string;           // 'enhance' | 'analyze' | ... | 'deploy'
  progress?: number;        // 0-100
  message?: string;         // Human-readable status
  data?: any;               // Phase result data
  sessionId?: string;       // e.g. "modgen-9e2521fb"
  manifestJSON?: string;    // Only on completion — massive JSON blob
}

Frontend Handling

  1. WorkflowStateService.startWorkflow() creates an EventSource to /module-generation/start
  2. Each SSE event updates signals: currentPhase, progress, moduleProgress
  3. On module-gen.completed, handleWorkflowComplete() fires — this is where Bug 10 occurs (6 synchronous blocking operations)

Reconnection


4. Database Persistence Architecture

Three Collections, Two Clusters

┌─────────────────────────────────────────────────────────────┐
│                    GoGrabSpace Cluster                       │
│                                                             │
│  ┌──────────────────────┐  ┌──────────────────────────────┐ │
│  │ ai-agents database   │  │ space_chrome-space-1_* DB    │ │
│  │                      │  │                              │ │
│  │ generated-modules    │  │ space_modules (1,615 docs)   │ │
│  │ (173 docs)           │  │ - Lightweight registry       │ │
│  │ - Full schema        │  │ - No actions/embeddables     │ │
│  │ - actions[]          │  │ - Written by frontend        │ │
│  │ - embeddables[]      │  │   via backend-api            │ │
│  │ - entities[]         │  │                              │ │
│  │ - Written by backend │  │                              │ │
│  │   via backend-ai-api │  │                              │ │
│  └──────────────────────┘  └──────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│                      Vitto Cluster                           │
│                                                             │
│  ┌──────────────────────────────────────────────────────┐   │
│  │ vitto-mind database                                   │   │
│  │                                                       │   │
│  │ generation_checkpoints (13 docs)                      │   │
│  │ - Pipeline progress tracking                          │   │
│  │ - Phase results for resume                            │   │
│  │ - Error messages on failure                           │   │
│  │ - TTL: 7 days for incomplete sessions                 │   │
│  │ - Written by backend-vitto-api                        │   │
│  └──────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘

Write Responsibility Matrix

Collection Writer When What Triggers It
generation_checkpoints backend-vitto-api Every phase completion Phase executor auto-saves
generated-modules backend-ai-api DEPLOY phase persistGeneratedModules() via HTTP
space_modules backend-api After frontend completion deployToUniverse() → createSpaceModule()

Upsert Strategy


5. JSON-to-Angular: How Modules Become UI

The Core Insight

Generated modules NEVER become static Angular component files. The .ts/.html/.scss code strings produced by the EXECUTE phase (Path B) are ephemeral — they exist only in the SSE payload and the manifestJSON blob. They are never compiled, written to disk, or executed as Angular code.

Instead, the platform uses a schema-driven dynamic rendering approach:

The Rendering Pipeline

1. AI generates structured JSON definitions:
   - actions[] → CRUD operations with typed inputs/outputs
   - embeddables[] → UI component specs with inputs/outputs
   - entities[] → Data model definitions

2. These are stored in `generated-modules` collection

3. At runtime, Angular reads these definitions via API

4. Generic rendering components interpret the JSON:
   - EmbeddableRenderer reads embeddable.category ("list", "widget", "form", "detail")
   - ActionFormRenderer reads action.inputs[] to build dynamic forms
   - EntityRenderer reads entity fields for validation

5. Result: Fully functional CRUD UI from pure JSON — no compilation needed

Embeddable Categories

Each module generates 4 embeddables:

Category Component Description
list {Entity}List Table/grid view with pagination, search, select, delete outputs
widget {Entity}Card Single-item card view
form {Entity}Form Create/edit form with all entity fields
detail {Entity}Detail Read-only detail view

Action Categories

Each module generates 5 CRUD actions:

Category Action Permissions Output
create create-{entity} {entity}:create Single entity
read list-{entity} {entity}:read Array of entities (paginated)
read get-{entity} {entity}:read Single entity by ID
update update-{entity} {entity}:update Updated entity
delete delete-{entity} {entity}:delete Boolean success

Input Type System

Actions define typed inputs that drive form rendering:

{ "name": "startTime", "type": "datetime", "required": true, "label": "Start Time" }
{ "name": "capacity", "type": "number", "required": false, "label": "Capacity" }
{ "name": "description", "type": "string", "required": false, "label": "Description" }
{ "name": "items", "type": "array", "label": "Class Items" }
{ "name": "item", "type": "object", "label": "Class data" }
{ "name": "loading", "type": "boolean", "label": "Loading state" }

Supported types: string, number, boolean, date, datetime, array, object

Why Code Strings Are Generated But Not Used

The outputMode: BOTH setting runs Path B after Path A, generating .ts, .html, .scss code per module. This:

Recommendation: Default to VISUAL_ONLY until the export feature is built.


6. Document Schemas (Full Reference)

generation_checkpoints

interface GenerationCheckpoint {
  _id: ObjectId;
  sessionId: string;                    // "modgen-{8-char-uuid}"
  request: {
    prompt: string;
    templateId?: string;
    spaceId: string;
    universeId: string;
    outputMode: 'visual' | 'code' | 'both';
  };
  status: 'in-progress' | 'completed' | 'failed';
  completedPhases: string[];            // ["enhance", "analyze", ...]
  currentPhase: string | null;          // null when completed
  tokensUsed: Record<string, number>;   // Per-phase token counts
  durationMs: number;                   // Total pipeline duration
  spaceId: string;
  universeId: string;                   // Internal long-form ID
  phaseResults: {
    completedAt?: Date;
    // Per-phase result data for resume
    enhance?: { enhancedPrompt: string };
    analyze?: { analysis: object };
    decompose?: { modules: ModuleSpec[] };
    plan?: { executionPlan: PlanItem[] };
    execute?: { generatedModules: GeneratedModule[] };
    integrate?: { integratedModules: object };
    deploy?: { deployedModules: object };
  };
  error?: string;                       // Error message when status = "failed"
  createdAt: Date;
  updatedAt: Date;
}

generated-modules

interface GeneratedModuleDoc {
  _id: ObjectId;
  moduleId: string;                     // "fitness-studio-class-management"
  spaceId: string;                      // "69250a03857479fe44376823"
  __v: number;

  // Core identity
  name: string;                         // "Class Management"
  slug: string;                         // "fitness-studio-class-management"
  description: string;                  // "Manage class data and operations"
  category: string;                     // "business" | "productivity" | "other"
  status: 'draft' | 'published';
  version: string;                      // "1.0.0"

  // Provenance
  createdBy: string;                    // "vibe-universe"
  universeId: string;                   // "universe_176859..."
  workflowId: string;                   // "workflow-177186..."

  // THE SCHEMA DATA — this is what drives the UI
  actions: Action[];                    // 5 CRUD actions (see above)
  embeddables: Embeddable[];            // 4 UI components (list, card, form, detail)
  entities: Entity[];                   // 1 data model definition

  // Extras
  manifestJSON: string;                 // Massive stringified JSON (includes code strings)
  metadata: object;                     // AI generation metadata
  routes: any[];                        // Empty for now
  tags: string[];                       // ["fitness", "management"]

  createdAt: Date;
  updatedAt: Date;
}

space_modules

interface SpaceModuleDoc {
  _id: string;                          // "mod-page-module-{slug}-{timestamp}"
  spaceId: string;
  name: string;
  slug: string;
  type: 'page-module';
  description: string;
  icon: string | null;
  extendsGlobal: string | null;
  isCustom: boolean;                    // true for generated modules
  moduleId: string;                     // Same as generated-modules.moduleId
  pageId: string | null;
  widgetId: string | null;
  route: string | null;
  position: string | null;
  defaultConfig: {
    layout: object | null;
    styles: object | null;
    ai: object | null;
    flows: object | null;
    flowTriggers: object | null;
    flowParams: object | null;
  };
  actions: null;                        // NOT populated (unlike generated-modules)
  scope: 'universe';
  universeId: string;
  isActive: boolean;
  order: number;
  createdAt: Date;
  updatedAt: Date;
  createdBy: string | null;
}

7. Key IDs & Mappings

The Universe ID Problem

The Angular route uses a human-readable slug, but the database stores an internal long-form ID:

Context Universe ID
Angular route param paks-uni-1
MongoDB universeId field universe_1768598939515_vfjz6wten
How resolved Frontend UniverseService maps slug → internal ID before API calls

Always use the internal ID when querying MongoDB directly.

Space ID

Context Value
Route param chrome-space-1
MongoDB spaceId 69250a03857479fe44376823
Database name space_chrome-space-1_79fe44376823

Session/Process ID Format

Type Format Example
Generation session modgen-{8-char-uuid} modgen-9e2521fb
Workflow ID workflow-{timestamp}-{random} workflow-1771862265114-wfw9kes
Module _id (space_modules) mod-page-module-{slug}-{timestamp} mod-page-module-fitness-studio-class-management-1768941199145

8. File Locations (Codebase Map)

Backend — Pipeline B (backend-vitto-api)

apis/backend-vitto-api/src/app/module-generation/
├── module-generation.controller.ts        # SSE endpoints: /start, /stream/:id, /status/:id, /resume/:id
├── module-generation.module.ts
├── module-gen-phase.executor.ts           # Central orchestrator for all 7 phases
├── session/
│   └── module-gen-session.manager.ts      # In-memory Map<string, Session> — lost on restart
├── checkpoint/
│   ├── checkpoint.schema.ts               # MongoDB schema for generation_checkpoints
│   └── checkpoint.service.ts              # Save/load checkpoints
├── phases/
│   ├── enhance.phase.ts
│   ├── analyze.phase.ts
│   ├── decompose.phase.ts
│   ├── plan.phase.ts
│   ├── execute.phase.ts                   # normalizeForMatch(), withTimeout(), emitProgress()
│   ├── integrate.phase.ts
│   └── deploy.phase.ts
└── prompts/
    ├── implement-visual.prompt.ts         # Path A: generates actions/embeddables/entities JSON
    └── implement.prompt.ts                # Path B: generates .ts/.html/.scss code strings

Backend — Module Persistence (backend-ai-api)

apis/backend-ai-api/src/app/workflow/
├── generated-modules.controller.ts        # POST /ai-api/modules (upsert)
├── generated-modules.service.ts
└── schemas/
    └── generated-module.schema.ts         # MongoDB schema with indexes

Backend — Space Modules (backend-api)

apis/backend-api/src/app/spaces/
├── space-modules.controller.ts            # POST /api/spaces/:spaceId/modules
└── space-modules.service.ts               # create() method

Backend — Vitto-to-AI Bridge

apis/backend-vitto-api/src/app/connectivity/
└── backend-ai-client.service.ts           # persistGeneratedModules() (lines 523-570)

Frontend — Vibe Universe Builder

libs/libs-structural/vibe-universe/src/lib/
├── components/
│   └── vibe-universe-generator/
│       └── vibe-universe-generator.component.ts   # Main component (2000+ lines)
│           # MAX_MODULES = 20
│           # autoSyncModulesToCanvas()
│           # deployToUniverse() — 8-step deploy flow
│           # reconnectToGeneration(processId)
│           # updateUrlWithProcessId()
└── vibe-universe.routes.ts                        # process/:processId child route

Frontend — Workflow State

libs/libs-ai/gograb-ai-lib/src/lib/services/
└── workflow-state.service.ts                      # startWorkflow(), resumeWorkflow(), handleWorkflowComplete()

Frontend — Module API

libs/libs-foundational/core-angular/src/lib/services/
└── backend-module-api.service.ts                  # createSpaceModule() (line 649)

9. Configuration & Defaults

Setting Default Location
outputMode BOTH controller.ts line 67/112
MAX_MODULES 20 vibe-universe-generator.component.ts
MODULE_GEN_TIMEOUT_MS 90,000 (90s) execute.phase.ts
Max LLM tokens (ANALYZE) 8,192 analyze.phase.ts
SSE replay buffer 50 events module-gen-session.manager.ts
Checkpoint TTL 7 days checkpoint.schema.ts

Port Configuration

Service Port Env Var
Frontend (space) 6200 GOGRAB_SPACE_PORT
backend-api 3000 —
backend-ai-api 3001 —
backend-docs-api 3002 —
backend-vitto-api 3003 —

API URL Tokens (Angular DI)

Token Import Backend Port
API_BASE_URL @libs-foundational/core-angular backend-api 3000
AI_API_URL @libs-foundational/api-config backend-ai-api 3001
DOCS_API_URL @libs-foundational/api-config backend-docs-api 3002
VITTO_API_URL @libs-foundational/api-config backend-vitto-api 3003

10. Known Bugs & Their Root Causes

Bug Description Root Cause Status Fix
1 enhancedPrompt.substring is not a function ENHANCE returned object, not string FIXED Unwrap response
2 executionPlan is not iterable PLAN returned { plan: [...] } wrapper FIXED Extract .plan
3 JSON truncation in ANALYZE maxTokens too low (4096) FIXED Raised to 8192 + parseLlmJson
4 Module name mismatch (EXECUTE skips) "Trainer Management" vs "trainer-management" FIXED normalizeForMatch()
5 Deploy fails (no modules persisted) Blocked by Bug 10 RETEST —
6 EXECUTE hangs 15+ min No timeout per LLM call FIXED withTimeout() 90s
7 Module limit truncation warnings MAX_MODULES = 8 too low FIXED Raised to 20
8 Tab crash after completion Evolved into Bug 10 → Bug 10 —
9 Progress UI uninformative No per-module feedback FIXED emitProgress() per module
10 Page Unresponsive at 100% 6 synchronous operations (2-5.5s blocking) CRITICAL Needs async yields
11 Page refresh → /landing Route guard redirects before space context loads HIGH Guard needs processId awareness
12 Backend DEPLOY may not persist persistGeneratedModules() may fail silently NEW Needs logging

Bug 10 Detail — The 6 Blocking Operations

When module-gen.completed SSE fires, these happen synchronously:

  1. JSON.parse(manifestJSON) — 500-2000ms (manifest is massive)
  2. platformSummary computed signal cascade — 300-800ms
  3. contextMode/contextSuggestions computed — 200-500ms
  4. JSON.stringify(state) + sessionStorage.setItem — 300-500ms
  5. buildGeneratedUniverseTree() — 200-500ms
  6. broadcastNodeCreate loop — 100-300ms

Total: 1.6-4.6 seconds of main-thread blocking → Chrome "Page Unresponsive"


11. Performance Data

Generation Times (from checkpoint data)

Session Duration Modules Per Module
modgen-bc4e5e7f 659,263ms (~11 min) 5 ~132s
modgen-2c719ae7 628,558ms (~10.5 min) 5 ~126s
modgen-ecb72414 643,947ms (~10.7 min) 5 ~129s
modgen-9e2521fb 662,652ms (~11 min) 5 ~133s

Average: ~10.8 minutes for 5 modules with outputMode: BOTH.

With VISUAL_ONLY, expect ~5.5 minutes (roughly half).

Collection Sizes

Collection Documents Storage
generation_checkpoints 13 —
generated-modules 173 544.77 kB
space_modules 1,615 —

12. Process Persistence (Session Recovery)

What Exists (Backend)

What Exists (Frontend)

What's Broken


13. Deploy to Universe Flow

The frontend's deployToUniverse() method runs an 8-step flow after generation completes:

Step 1: Extract modules from generation result
Step 2: Map modules to SpaceModule format
Step 3: For each module:
         POST /api/spaces/:spaceId/modules
         (creates space_modules document)
Step 4: Build navigation tree
Step 5: Update universe metadata
Step 6: Sync modules to canvas (replaceTree + hydrateFromModules)
Step 7: Save state to sessionStorage
Step 8: Broadcast node creation events

Critical dependency: This entire flow runs on the frontend after the completion SSE event. If the frontend freezes (Bug 10), none of this executes.


14. Testing Checklist

When testing the generation pipeline, verify: