Skip to main content

Marketplace Architecture

The marketplace module follows the domain-based architecture pattern of the BuildAppsWith platform, providing a dedicated set of files for builder discovery, profile management, and analytics functionality.

Module Structure

The marketplace module is organized as follows:
/lib/marketplace/
├── actions.ts                 # Server actions
├── api.ts                     # Client-side API functions
├── schemas.ts                 # Zod schemas
├── types.ts                   # Type definitions (consolidated)
├── utils.ts                   # Utility functions
├── index.ts                   # Barrel exports
├── marketplace-service.ts     # Core marketplace data operations
├── analytics-service.ts       # Analytics-specific operations
└── data-service.DEPRECATED.md # Documentation for deprecated service

/components/marketplace/
├── components/                # Component implementations
│   ├── builder-card/          # Builder card component directory
│   │   ├── builder-card.tsx   # Main component implementation
│   │   ├── card-skeleton.tsx  # Loading skeleton implementation
│   │   └── index.ts           # Barrel exports
│   ├── builder-image/         # Consolidated builder image component
│   │   ├── builder-image.tsx  # Main component implementation
│   │   ├── fallback.tsx       # Fallback component for errors/missing images
│   │   └── index.ts           # Barrel exports
│   ├── builder-list/          # List component directory
│   │   ├── builder-list.tsx   # Main list component
│   │   └── index.ts           # Barrel exports
│   ├── error-boundaries/      # Error handling components
│   ├── filter-panel/          # Filter UI components
│   └── types.ts               # Component-specific type definitions
├── hooks/                     # Custom React hooks
│   ├── use-builder-filter.ts  # Filter state management
│   ├── use-builder-search.ts  # Search functionality
│   └── index.ts               # Barrel exports for hooks
└── utils/                     # Component utility functions

Architecture Principles

1. Separation of Concerns

  • Client-side vs Server-side: Clear separation between client API functions (api.ts) and server-side data services (data/marketplace-service.ts)
  • Domain Boundaries: The marketplace module encapsulates all marketplace-related functionality
  • Type Safety: Shared types defined in types.ts ensure consistency across the module

2. API Design

The module exposes three primary API areas:
  1. Builder Discovery: Functions for searching, filtering, and fetching builder profiles
  2. Analytics: Functions for accessing and analyzing builder performance metrics
  3. Filter Management: Functions for retrieving marketplace filter options

3. Component Structure

The marketplace components follow a standardized structure:
  • One Component Per Directory: Each component has its own directory
  • Consistent File Naming: Component files match their directory names
  • Barrel Exports: Index files export the main component
  • Specialized Supporting Files: Fallbacks, skeletons, and utilities grouped with parent components
  • Implementation Design: Stateless components where possible with clear separation of concerns
  • Utility Integration: Components leverage shared utilities like cn() for class name merging

4. Error Handling

  • Error Boundaries: Components are wrapped in error boundaries for isolation at the UI level
  • Inline Error Handling: Components handle errors inline with fallbacks (e.g., for failed image loading)
  • Graceful Degradation: Components degrade gracefully without user-facing error messages
  • Type Validation: Components use type validation to prevent common errors
  • Dedicated Fallback Components: Each error scenario has a dedicated fallback component
For example, the BuilderImage component implements multi-layered error handling:
// Source validation
const hasValidImageSrc = Boolean(src) && 
  (src?.startsWith('/') || src?.startsWith('http'));
  
// Conditional rendering based on validation
{hasValidImageSrc ? (
  <Image
    // Image implementation
    onError={(e) => {
      // On-load error handling
      const imgElement = e.currentTarget as HTMLImageElement;
      imgElement.style.display = 'none';
    }}
  />
) : (
  // Fallback component for invalid source
  <ImageFallback text={alt} size={size} />
)}

5. State Management

  • Stateless Design: Components are stateless where possible:
    • State management moved to hooks
    • Pure render functions for predictable behavior
    • No complex useEffect dependencies
    • Implementation avoids unnecessary re-renders
    • Efficient error handling without state changes
For example, instead of using state to track image loading errors:
// AVOID: Using state for error handling
const [imageError, setImageError] = useState(false);

// PREFERRED: Direct DOM manipulation for errors
onError={(e) => {
  const imgElement = e.currentTarget as HTMLImageElement;
  imgElement.style.display = 'none';
}}

6. Data Flow

Key Design Decisions

Design Decision: Hybrid Architecture

The marketplace module uses a hybrid architecture that combines:
  • Client-side API functions in api.ts (follow REST patterns)
  • Server-side data services in the data/ directory (database operations)
This approach allows for:
  • Clean separation between presentation and data access
  • Optimized data operations on the server
  • Secure access control at the API route level

Design Decision: Consolidated Type System

All marketplace types are defined in a single types.ts file, which serves as the source of truth for:
  • Builder profile structures
  • Marketplace filters
  • Analytics data structures
Types are now properly separated into:
  • Domain Types (lib/marketplace/types.ts) - Core business logic types used by services and server components
  • Component Types (components/marketplace/components/types.ts) - UI-specific types that prevent circular dependencies
This consolidation ensures consistency across client and server implementations while simplifying maintenance.

Design Decision: Feature Flagging

The marketplace module supports feature flagging through:
  • Demo account handling
  • Feature-specific filters
  • Environment-based configuration

Implementation Principles

Client-Side API Functions

Client-side API functions in api.ts:
  • Use fetch to call API endpoints
  • Handle error states gracefully
  • Return typed responses
  • Support pagination and filtering
Example:
export async function fetchBuilders(
  page: number = 1, 
  limit: number = 9,
  filters?: MarketplaceFilters
): Promise<BuildersResponse> {
  // Implementation...
}

Server-Side Data Services

Server-side data services in data/marketplace-service.ts:
  • Perform direct database operations
  • Implement business logic
  • Handle data transformations
  • Manage security and access control
Example:
export async function fetchBuilders(
  page: number = 1,
  limit: number = 9,
  filters?: MarketplaceFilters
): Promise<PaginatedResponse<BuilderProfileListing>> {
  // Database operations & business logic...
}

Evolution & Migration

The marketplace module has evolved from a simple list of builders to a comprehensive marketplace for developer services. Key migrations include:
  1. Addition of analytics capabilities
  2. Enhanced filtering options
  3. Migration to the domain-based architecture
  4. Consolidation of duplicated code
Recent improvements focused on eliminating duplication between:
  • api.ts and data-service.ts (client-side operations) - with data-service.ts now deprecated
  • Multiple builder image implementations consolidated into a single component
  • Type definitions consolidated into domain and component-specific files

Deprecated Components

The following components have been deprecated and will be removed in future updates:
  • components/marketplace/builder-image.tsx → Use components/marketplace/components/builder-image
  • components/marketplace/simplified-builder-image.tsx → Use components/marketplace/components/builder-image
  • components/marketplace/fixed-builder-image.tsx → Use components/marketplace/components/builder-image
  • lib/marketplace/data-service.ts → Use lib/marketplace/marketplace-service.ts

Future Directions

Planned enhancements to the marketplace architecture include:
  1. Full migration to Nx libraries: Moving the marketplace module to a dedicated Nx library
  2. Enhanced analytics: More comprehensive builder performance metrics
  3. API versioning: Supporting multiple versions of the marketplace API
  4. GraphQL integration: Adding GraphQL support for more flexible data fetching