Files
metabuilder/frontends/codegen/CLAUDE.md
2026-03-09 22:30:41 +00:00

14 KiB

Claude Code Documentation

Architecture Overview

This is a low-code React application builder that is migrating from TypeScript/TSX components to a JSON-driven architecture.

Current State (Jan 2026)

  • ~420 TSX files in src/components/ (legacy - being phased out)
  • 338 JSON definitions in src/config/pages/ (target architecture)
  • 342 entries in json-components-registry.json
  • 19 complete JSON implementations in src/components/json-definitions/
  • 141 duplicate TSX files deleted (had JSON equivalents)
  • 5 atoms remaining to convert: Accordion, FileUpload, Image, Menu, Popover
  • 1 molecule remaining: BindingEditor
  • 3 organisms remaining: DataSourceManager, NavigationMenu, TreeListPanel

Migration Strategy

Core Principle

ALL components can be converted to JSON except the application entrypoint, because custom hooks can handle any stateful/complex logic.

Directory Structure

src/
├── components/              # 🔴 LEGACY - Phase out
│   ├── atoms/              # Basic UI components (6 TSX remaining)
│   │   ├── json-ui/        # JSON-specific atoms
│   │   ├── Accordion.tsx
│   │   ├── FileUpload.tsx
│   │   ├── Image.tsx
│   │   ├── Menu.tsx
│   │   └── Popover.tsx
│   ├── molecules/          # Composite components (1 TSX remaining)
│   │   └── BindingEditor.tsx
│   ├── organisms/          # Complex feature components (3 TSX remaining)
│   │   ├── DataSourceManager.tsx
│   │   ├── NavigationMenu.tsx
│   │   └── TreeListPanel.tsx
│   └── json-definitions/   # ✅ JSON implementations (19 files)
│       ├── loading-fallback.json
│       ├── navigation-item.json
│       ├── page-header-content.json
│       ├── component-binding-dialog.json
│       ├── data-source-editor-dialog.json
│       ├── github-build-status.json
│       ├── save-indicator.json
│       ├── component-tree.json
│       ├── seed-data-manager.json
│       ├── lazy-d3-bar-chart.json
│       ├── storage-settings.json
│       ├── tree-card.json
│       ├── filter-input.json
│       ├── copy-button.json
│       ├── input.json
│       └── password-input.json
│
├── config/
│   ├── pages/              # ✅ TARGET - JSON definitions (338 files)
│   │   ├── atoms/          # JSON schema for atoms
│   │   ├── molecules/      # JSON schema for molecules
│   │   ├── organisms/      # JSON schema for organisms
│   │   ├── templates/      # Page templates
│   │   └── *.json          # Page definitions
│   └── pages.json          # Central routing manifest
│
├── hooks/                  # ✅ Custom hooks for JSON components
│   ├── use-save-indicator.ts
│   ├── use-component-tree.ts
│   ├── use-storage-backend-info.ts
│   ├── use-d3-bar-chart.ts
│   ├── use-focus-state.ts      # NEW: For FilterInput
│   ├── use-copy-state.ts       # NEW: For CopyButton
│   ├── use-password-visibility.ts  # NEW: For PasswordInput
│   └── index.ts
│
├── lib/
│   └── json-ui/
│       ├── component-registry.ts         # Component resolver
│       ├── component-renderer.tsx        # JSON → React renderer
│       ├── json-components.ts            # JSON component exports (27 components)
│       ├── create-json-component.tsx     # Pure JSON component factory
│       ├── create-json-component-with-hooks.tsx  # JSON + hooks factory
│       ├── hooks.ts                      # Data source/action hooks
│       ├── hooks-registry.ts             # Hook registration (12 hooks registered)
│       ├── constants/                    # Shared constants for JSON transforms
│       │   ├── sizes.ts                  # Button sizes, icon sizes, dimensions
│       │   ├── placements.ts             # Popover/tooltip positioning
│       │   ├── styles.ts                 # Common CSS classes (transitions, animations, etc.)
│       │   ├── object-fit.ts             # Image object-fit classes
│       │   └── index.ts
│       └── interfaces/                   # TypeScript interfaces (1 per file)
│           ├── loading-fallback.ts
│           ├── navigation-item.ts
│           ├── page-header-content.ts
│           ├── save-indicator.ts
│           ├── lazy-bar-chart.ts
│           ├── lazy-line-chart.ts
│           ├── lazy-d3-bar-chart.ts
│           ├── seed-data-manager.ts
│           ├── storage-settings.ts
│           ├── github-build-status.ts
│           ├── component-binding-dialog.ts
│           ├── data-source-editor-dialog.ts
│           ├── component-tree.ts
│           ├── tree-card.ts
│           ├── filter-input.ts
│           ├── copy-button.ts
│           ├── input.ts
│           ├── password-input.ts
│           ├── image.ts
│           ├── popover.ts
│           ├── menu.ts
│           ├── file-upload.ts
│           ├── accordion.ts
│           └── index.ts
│
├── scripts/                # Migration and audit tools
│   ├── audit-json-components.ts
│   ├── analyze-duplicates.ts
│   ├── cleanup-registry.ts
│   └── fix-index-files.ts
│
└── json-components-registry.json   # Master component registry

How It Works

1. Routing Flow

pages.json → json-components-registry.json → Component Implementation

Example:

// pages.json
{
  "id": "dashboard",
  "component": "ProjectDashboard"
}

// json-components-registry.json
{
  "type": "ProjectDashboard",
  "source": "organisms",
  "load": {
    "path": "@/components/ProjectDashboard",
    "export": "ProjectDashboard"
  }
}

2. Component Types

Pure JSON Components (No Hooks)

Simple stateless components defined entirely in JSON:

// src/components/json-definitions/tree-card.json
{
  "id": "tree-card-container",
  "type": "Card",
  "bindings": {
    "className": {
      "source": "isSelected",
      "transform": "data ? 'ring-2 ring-primary' : 'hover:bg-accent/50'"
    }
  },
  "children": [...]
}

Exported from src/lib/json-ui/json-components.ts:

import treeCardDef from '@/components/json-definitions/tree-card.json'
export const TreeCard = createJsonComponent<TreeCardProps>(treeCardDef)

JSON Components with Hooks

Stateful components using custom hooks (NO WRAPPER FILES NEEDED):

// src/lib/json-ui/json-components.ts
export const ComponentTree = createJsonComponentWithHooks<ComponentTreeProps>(
  componentTreeDef,
  {
    hooks: {
      treeData: {
        hookName: 'useComponentTree',
        args: (props) => [props.components || [], props.selectedId || null]
      }
    }
  }
)

The custom hook is defined in src/hooks/use-component-tree.ts (or other hook files) and registered in src/lib/json-ui/hooks-registry.ts.

TSX Components (Legacy)

Currently imported directly - these need migration:

// ❌ OLD: Direct TSX import
import { AppBranding } from '@/components/molecules/AppBranding'

// ✅ NEW: JSON-based import
import { AppBranding } from '@/lib/json-ui/json-components'

3. Registry System

The json-components-registry.json defines how components are loaded:

{
  "type": "SaveIndicator",
  "source": "molecules",
  "jsonCompatible": true
}
  • jsonCompatible: Whether component can be expressed as JSON
  • load.path: Explicit path to component file (for TSX legacy components)
  • source: Where the component comes from (atoms, molecules, organisms, ui)

Note: wrapperRequired and wrapperComponent fields in the registry are obsolete and should be removed. All stateful logic is handled via createJsonComponentWithHooks.

Current Issues (Jan 2026)

Audit Results

Run npm run audit:json to see current status:

  • Errors

    • 6 orphaned JSON files (no registry entry)
    • 7 broken load paths
  • ⚠️ 153 warnings

    • 153 duplicate implementations (TSX + JSON)

Critical Tasks

  1. Phase Out src/components/

    • 153 components have both TSX and JSON definitions
    • TSX versions should be deleted and routed through JSON
  2. Clean Up Registry

    • Remove wrapperRequired and wrapperComponent fields (obsolete)
    • All stateful logic is handled via createJsonComponentWithHooks
    • Custom hooks defined in src/lib/json-ui/hooks.ts
  3. Fix Registry Issues

    • Add missing registry entries for orphaned JSON
    • Fix broken load paths
    • Verify all source mappings

Migration Checklist

For each component:

  • Create JSON definition in src/components/json-definitions/
  • Add TypeScript interface in src/lib/json-ui/interfaces/ (one file per interface)
  • If stateful: Define custom hook in src/hooks/use-[component-name].ts
  • If stateful: Register hook in src/lib/json-ui/hooks-registry.ts
  • If stateful: Export hook from src/hooks/index.ts
  • Export from src/lib/json-ui/json-components.ts:
    • Use createJsonComponent for pure/stateless
    • Use createJsonComponentWithHooks for stateful
  • Update registry in json-components-registry.json
  • Update all imports to use @/lib/json-ui/json-components
  • Delete legacy TSX file from src/components/
  • Run tests and build to verify

Useful Commands

# Run audit to check migration status
npm run audit:json

# Generate component types
npm run components:generate-types

# Build (will fail if components missing)
npm run build

Key Files

  • json-components-registry.json - Master registry of all components
  • src/config/pages.json - Page routing configuration
  • src/lib/json-ui/component-registry.ts - Component resolver logic
  • src/lib/json-ui/json-components.ts - JSON component exports
  • src/lib/json-ui/hooks.ts - Custom hooks for stateful components
  • src/lib/json-ui/hooks-registry.ts - Hook registration
  • scripts/audit-json-components.ts - Audit tool

Notes

  • Never create new TSX components - use JSON instead
  • All components can be JSON except the app entrypoint
  • Use custom hooks for stateful logic (via createJsonComponentWithHooks)
  • NO wrapper files needed - hooks are defined in hooks.ts and registered in hooks-registry.ts
  • One interface per file in src/lib/json-ui/interfaces/
  • Meta JSON files in src/config/pages/ are routing schemas
  • Full JSON definitions live in src/components/json-definitions/

Recent Changes (Jan 2026)

Phase 1: Setup & Cleanup

  • Fixed e2e build failures (TreeCard, TreeListHeader routing)
  • Removed 8 initial duplicate TSX files with JSON equivalents
  • Split wrapper-interfaces.ts into individual interface files
  • Created audit script to track migration progress
  • Updated imports to use @/lib/json-ui/json-components
  • Clarified: NO wrapper system - use JSON + custom hooks

Phase 2: Mass Cleanup

  • Cleaned registry - removed 107 obsolete wrapperRequired/wrapperComponent fields
  • Analyzed 153 duplicates, categorized safe deletions
  • Deleted 141 duplicate TSX files (had complete JSON implementations)
  • Created fix-index-files.ts script to auto-update exports

Phase 3: Active Conversions (In Progress)

  • Converted FilterInput to JSON with useFocusState hook
  • Converted CopyButton to JSON with useCopyState hook
  • Converted Input to JSON (pure component with forwardRef support)
  • Converted PasswordInput to JSON with usePasswordVisibility hook
  • Moved custom hooks from lib/json-ui/hooks.ts to src/hooks/ directory
  • Created use-focus-state.ts, use-copy-state.ts, and use-password-visibility.ts
  • Updated hooks-registry.ts to include 7 registered hooks

Remaining Work

  • 🔄 5 atoms left: Accordion, FileUpload, Image, Menu, Popover
  • 🔄 1 molecule left: BindingEditor
  • 🔄 3 organisms left: DataSourceManager, NavigationMenu, TreeListPanel
  • 20 JSON components complete (up from 12)

Phase 14: 100% JSON Coverage or Framework-Only Categorization (Jan 2026)

Completion Analysis

Components Categorization

Framework-Essential (TSX Only - DO NOT CONVERT):

  • UI Library components (Shadcn/Radix): 173 files
    • sidebar (23), menubar (17), dropdown-menu (16), context-menu (16), alert-dialog (12), select (11), command (10), navigation-menu (9), form (9), chart (8), carousel (7), and 36 others
  • App Bootstrap & Routing: 7 files
    • AppBootstrap, AppRouterBootstrap, AppLayout, AppRouterLayout, AppMainPanel, AppDialogs, LoadingScreen
  • Total Framework-Essential: 180 files (43.7%)

Application Code (Can Convert to JSON):

  • Demo & Showcase: 15 files
  • Business Logic Components: 200+ files
    • Designer tools, Builders, Feature modules, Specialized tools
  • Documentation Views: 41 files
  • Total Convertible: 256+ files (62.3%)

Final Coverage Achievement

Current Status:

  • Total TSX files: 412
  • Total JSON definitions: 337
  • Registry entries: 373
  • Build status: Clean (0 audit issues)
  • JSON compatibility: 62.3% of all components

What "100% JSON" Means:

  • Cannot achieve 100% because UI framework (Radix/Shadcn) requires 173 TSX primitives
  • Cannot achieve 100% because app routing requires 7 TSX bootstrap files
  • CAN achieve 62.3% overall JSON coverage
  • CAN achieve 100% JSON for application business logic (excluding framework)

Key Insight

The true goal is maximum JSON for user-facing code while respecting framework requirements:

  • Framework layer (UI + Router): 180 files must remain TSX
  • Application layer: 256+ files can be JSON
  • Achievable JSON coverage: 62.3% (optimal for this architecture)

Architecture Decision

Phase 14 categorization created a clear two-tier architecture:

  1. Tier 1 - Framework (TSX): UI primitives, routing, providers
  2. Tier 2 - Application (JSON): Business logic, tools, features

This represents the natural boundary between framework infrastructure and user application code.

Next Steps

  1. Complete Phase 14 categorization (audit complete)
  2. If needed in future phases: Migrate remaining 256+ application components to JSON
  3. Maintain clean separation: Framework layer (TSX) vs Application layer (JSON)
  4. For new components: Always use JSON + custom hooks pattern