Widgets Backend Analysis

Ecosistema completo para organización y gestión de contenido con interfaces espaciales

Backend API Widget Architecture - Complete Analysis

Date: December 9, 2025
Session: 9
Status: ✅ Analysis Complete


🎯 Executive Summary

The backend has a three-tier widget architecture that was not fully documented:

  1. Global Widgets - Platform-wide widgets (gograb-api database)
  2. Space Widgets - Per-space custom widgets (space-specific databases)
  3. Widget Modules - Modular wrappers around widgets (space-specific databases)

📊 Backend Storage Architecture

Database Structure

┌─────────────────────────────────────────────────────────────────────────────┐
│  DATABASE: gograb-api (Platform Database)                                   │
├─────────────────────────────────────────────────────────────────────────────┤
│  Collection: widgets (Global Widgets)                                       │
│  Schema: GlobalWidget                                                       │
│  Purpose: Platform-wide reusable widgets                                    │
│  Examples: Button, Input, Card, etc.                                        │
│                                                                             │
│  Fields:                                                                    │
│    - _id (string, unique)                                                   │
│    - name, version, type, description, icon, category                       │
│    - defaultConfig (Record<string, unknown>)                                │
│    - propertyConfig (WidgetPropertyConfig)                                  │
│    - variants (WidgetVariant[])                                             │
│    - defaultVariant (string)                                                │
│    - ai (ResourceAIMetadata)                                                │
│    - isCore, isPremium, isPublic, isActive                                  │
│    - author, tags                                                           │
│    - createdAt, updatedAt                                                   │
└─────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────────┐
│  DATABASE: space_{spaceId}_{shortId} (Per-Space Database)                  │
├─────────────────────────────────────────────────────────────────────────────┤
│  Collection: space_widgets (Space Widgets)                                  │
│  Purpose: Custom widgets created by space users                             │
│  API Endpoints: /api/spaces/:spaceId/widgets                                │
│                                                                             │
│  Fields:                                                                    │
│    - id (string) - widget_{timestamp}_{random}                              │
│    - name, type, category, description, icon                                │
│    - spaceId (string)                                                       │
│    - scope ('private' | 'public')                                           │
│    - variants (array of variant objects)                                    │
│    - defaultVariant (string)                                                │
│    - defaultConfig (Record<string, unknown>)                                │
│    - propertyConfig (object)                                                │
│      - groups (PropertyGroup[])                                             │
│      - values (Record<string, unknown>)                                     │
│    - usage (object)                                                         │
│      - usedInUniverses (string[])                                           │
│      - usedInPages (string[])                                               │
│      - instanceCount (number)                                               │
│    - metadata (object)                                                      │
│      - created, modified, author, version, tags                             │
│                                                                             │
│  Collection: widget_modules (Widget Modules)                                │
│  Purpose: Modular wrappers around widgets with embeddable components        │
│  API Endpoints: /api/spaces/:spaceId/widget-modules                         │
│                                                                             │
│  Fields:                                                                    │
│    - id (string) - wm_{timestamp}_{random}                                  │
│    - name, description, version, type, icon, category, tags                 │
│    - spaceId (string)                                                       │
│    - scope ('private' | 'public')                                           │
│    - sourceWidgetId (string) - references space_widgets                     │
│    - sourceWidgetType (string)                                              │
│    - embeddableComponents (array)                                           │
│    - inputs (array) - module parameter metadata                             │
│    - outputs (array) - module output metadata                               │
│    - defaultConfig (Record<string, unknown>)                                │
│    - propertyGroups (array)                                                 │
│    - usage (object)                                                         │
│      - installCount, usedInUniverses, usedInSpaces                          │
│    - metadata (created, modified, author, license, repository, docs)        │
│    - dependencies (string[])                                                │
└─────────────────────────────────────────────────────────────────────────────┘

🔌 Backend API Endpoints

Global Widgets API

Service: GlobalResourcesService
Controller: GlobalResourcesController
Base Path: /api/global-resources/

GET    /api/global-resources/widgets        // List all global widgets
GET    /api/global-resources/widgets/:id    // Get global widget
POST   /api/global-resources/widgets        // Create global widget
PUT    /api/global-resources/widgets/:id    // Update global widget
DELETE /api/global-resources/widgets/:id    // Delete global widget

Space Widgets API

Service: WidgetsService
Controller: WidgetsController
Base Path: /api/spaces/:spaceId/widgets

GET    /api/spaces/:spaceId/widgets           // List space widgets
GET    /api/spaces/:spaceId/widgets/:id       // Get widget
POST   /api/spaces/:spaceId/widgets           // Create widget
PUT    /api/spaces/:spaceId/widgets/:id       // Update widget
DELETE /api/spaces/:spaceId/widgets/:id       // Delete widget

Widget Modules API

Service: WidgetModulesService
Controller: WidgetModulesController
Base Path: /api/spaces/:spaceId/widget-modules

GET    /api/spaces/:spaceId/widget-modules                // List modules
GET    /api/spaces/:spaceId/widget-modules/:id            // Get module
POST   /api/spaces/:spaceId/widget-modules                // Create module
PUT    /api/spaces/:spaceId/widget-modules/:id            // Update module
DELETE /api/spaces/:spaceId/widget-modules/:id            // Delete module
GET    /api/spaces/:spaceId/widget-modules/by-source/:widgetId  // Get by source widget

Core Widgets API

Service: CoreWidgetsService
Database: gograb-api
Collection: core_widgets

Internal service for managing core/built-in widgets.


📦 Widget Data Model

CreateWidgetDto (Frontend → Backend)

interface CreateWidgetDto {
  id?: string;
  name: string;
  type: string;
  category: string;
  description?: string;
  icon?: string;
  scope?: 'private' | 'public';
  variants?: Array<{
    id: string;
    name: string;
    description?: string;
    properties: Record<string, unknown>;
    preview?: string;
    createdAt?: string;
    updatedAt?: string;
  }>;
  defaultVariant?: string;
  defaultConfig?: Record<string, unknown>;
  propertyConfig?: {
    groups: Array<{
      id: string;
      title: string;
      properties: Array<{
        key: string;
        label: string;
        type: string;
        defaultValue?: unknown;
      }>;
    }>;
    values: Record<string, unknown>;
  };
  metadata?: {
    author?: string;
    version?: string;
    tags?: string[];
  };
}

WidgetResponse (Backend → Frontend)

interface WidgetResponse {
  id: string;
  name: string;
  type: string;
  category: string;
  description: string;
  icon: string;
  spaceId: string;
  scope: 'private' | 'public';
  variants: Array<{
    id: string;
    name: string;
    description: string;
    properties: Record<string, unknown>;
    preview?: string;
    createdAt: string;
    updatedAt: string;
  }>;
  defaultVariant: string;
  defaultConfig: Record<string, unknown>;
  propertyConfig: {
    groups: Array<{
      id: string;
      title: string;
      properties: Array<{
        key: string;
        label: string;
        type: string;
        defaultValue?: unknown;
      }>;
    }>;
    values: Record<string, unknown>;
  };
  usage: {
    usedInUniverses: string[];
    usedInPages: string[];
    instanceCount: number;
  };
  metadata: {
    created: string;
    modified: string;
    author: string;
    version: string;
    tags: string[];
  };
}

🔄 The Three-Tier Architecture

Tier 1: Global Widgets (Platform Level)

Purpose: Platform-wide reusable widgets
Database: gograb-api
Collection: widgets
Managed By: GoGrab Team
Examples: Button, Input, Card, Hero, Gallery

Characteristics:

Tier 2: Space Widgets (Space Level)

Purpose: Custom widgets created by space users
Database: space_{spaceId}_{shortId}
Collection: space_widgets
Managed By: Space users
Examples: Custom contact form, pricing table, etc.

Characteristics:

Tier 3: Widget Modules (Module Level)

Purpose: Modular wrappers around widgets
Database: space_{spaceId}_{shortId}
Collection: widget_modules
Managed By: Space users

Characteristics:

Key Difference: Widget Modules wrap widgets to make them modular and embeddable in other contexts.


💡 Key Insights

1. Widget Modules Already Exist!

The backend already has a WidgetModulesService that wraps widgets into modular components. This is the missing link between simple widgets and the module system.

Flow:

Widget Builder → Creates Space Widget → Optionally wraps in Widget Module

2. Variants Are Built Into Backend

The backend fully supports variants:

The frontend just needs to connect to this!

3. Property Groups Are Backend-Supported

The backend stores property groups in propertyConfig.groups:

propertyConfig: {
  groups: [{
    id: 'appearance',
    title: 'Appearance',
    properties: [
      { key: 'color', label: 'Color', type: 'color', defaultValue: '#000' }
    ]
  }],
  values: { color: '#ff0000' }
}

4. The Missing NX Library Generation

What's NOT in the backend:

This is the gap identified in Priority 5.


🎯 How Frontend Should Use Backend

For Simple Widgets (Current)

// Widget Builder saves to space_widgets
const widget = await http.post(`/api/spaces/${spaceId}/widgets`, {
  name: 'My Widget',
  type: 'custom',
  category: 'content',
  variants: [{ /* variant */ }],
  propertyConfig: { /* property groups */ }
});

For Widget Modules (Should Add)

// After creating widget, optionally create module wrapper
const widgetModule = await http.post(`/api/spaces/${spaceId}/widget-modules`, {
  name: 'My Widget Module',
  sourceWidgetId: widget.id,
  embeddableComponents: [{ /* embeddable */ }],
  inputs: [{ /* inputs */ }],
  outputs: [{ /* outputs */ }]
});

For Variants (Should Add to Frontend)

// Smart Variant Creator should save to backend
const widget = await http.get(`/api/spaces/${spaceId}/widgets/${widgetId}`);

// Add new variant
widget.variants.push({
  id: `variant_${Date.now()}`,
  name: 'New Variant',
  description: 'Description',
  properties: { /* configured properties */ }
});

// Update widget
await http.put(`/api/spaces/${spaceId}/widgets/${widgetId}`, widget);

🔄 Complete Widget Lifecycle

┌─────────────────────────────────────────────────────────────────────────────┐
│  1. CREATION                                                                 │
│     Widget Builder → POST /api/spaces/:spaceId/widgets                      │
│     └─> Saves to space_{spaceId}.space_widgets                              │
├─────────────────────────────────────────────────────────────────────────────┤
│  2. VARIANT CREATION                                                         │
│     Smart Variant Creator → Update widget.variants array                    │
│     └─> PUT /api/spaces/:spaceId/widgets/:id                                │
├─────────────────────────────────────────────────────────────────────────────┤
│  3. MODULE WRAPPING (Optional)                                               │
│     Widget Module Creator → POST /api/spaces/:spaceId/widget-modules        │
│     └─> References sourceWidgetId                                           │
├─────────────────────────────────────────────────────────────────────────────┤
│  4. USAGE                                                                    │
│     Page Editor → Uses widget via WidgetHostComponent                       │
│     └─> Loads from embeddable registry or backend                           │
├─────────────────────────────────────────────────────────────────────────────┤
│  5. USAGE TRACKING                                                           │
│     Backend tracks usage.usedInUniverses, usage.usedInPages                 │
│     └─> Updated automatically when widget is used                           │
└─────────────────────────────────────────────────────────────────────────────┘

🎯 Action Items for Frontend

Priority 2: Variant Creator Integration ✅

Backend Support: ✅ Full support
API: PUT /api/spaces/:spaceId/widgets/:id
Implementation: Update variants array in widget

Priority 3: Widget Builder Consolidation

Backend Support: ✅ Full support
API: POST /api/spaces/:spaceId/widgets
Ensure: Property groups are saved in propertyConfig.groups

Priority 5: Widget Module Integration

Backend Support: ✅ Full support via WidgetModulesService
API: POST /api/spaces/:spaceId/widget-modules
Implementation: Add "Save as Module" option that creates widget module


📊 Summary

The backend has a complete, robust widget system with:

What's Missing: Frontend integration with these APIs, especially:

  1. Variant creation/editing UI
  2. Widget module creation
  3. NX library generation (Priority 5)

Document Version: 1.0
Session: 9
Status: ✅ Complete
Next: Implement Priority 2 using these APIs