cuatrolabs-scm-ms / docs /api-guides /UI_API_INTEGRATION_PROMPT.md
MukeshKapoor25's picture
merchant fixes
63f05fb

UI API Integration Prompt Instructions

🎯 System Overview

You are building a UI for a hierarchical B2B beauty supply chain management system. The backend provides REST APIs for managing merchants in a 4-level hierarchy: Parent Company β†’ cnf β†’ distributors β†’ retails.

πŸ—οΈ API Base Configuration

Base URL & Authentication

const API_BASE_URL = 'http://localhost:8000'
const API_ENDPOINTS = {
  merchants: '/merchants',
  merchantSettings: '/merchant-settings',
  users: '/system-users',
  roles: '/access-roles',
  auth: '/auth'
}

// JWT Token Authentication (implement as needed)
const apiHeaders = {
  'Content-Type': 'application/json',
  'Authorization': `Bearer ${localStorage.getItem('authToken')}`
}

Test Credentials for Development

const TEST_CREDENTIALS = {
  superAdmin: { username: 'superadmin', password: 'SuperAdmin@123' },
  companyAdmin: { username: 'companyadmin', password: 'CompanyAdmin@123' },
  cnfManager: { username: 'cnfmanager_north', password: 'cnfManager@123' },
  distManager: { username: 'distmanager_delhi', password: 'DistManager@123' },
  retailOwner: { username: 'owner_cp_luxury', password: 'retailOwner@123' }
}

πŸ“± Core UI Components to Build

1. Merchant Hierarchy Tree View

// GET /merchants - Fetch all merchants
const fetchMerchantsHierarchy = async () => {
  const response = await fetch(`${API_BASE_URL}/merchants`, {
    headers: apiHeaders
  })
  const merchants = await response.json()
  
  // Build tree structure
  return buildHierarchyTree(merchants)
}

// Expected merchant object structure:
const merchantStructure = {
  merchant_id: "string",
  merchant_name: "string", 
  merchant_type: "parent_company|cnf|distributor|retail",
  merchant_code: "string",
  parent_merchant_id: "string|null",
  status: "active|inactive",
  contact: {
    phone: "string",
    email: "string", 
    address_line1: "string",
    city: "string",
    state: "string",
    pincode: "string"
  },
  kyc: { /* GST, PAN details */ }
}

2. Merchant Management Dashboard

Create these UI sections:

A. Merchant List/Grid View

// API Calls:
// GET /merchants?merchant_type=retail - Filter by type
// GET /merchants?status=active - Filter by status  
// GET /merchants/children/{parent_id} - Get child merchants

const merchantListConfig = {
  columns: [
    { key: 'merchant_code', label: 'Code', sortable: true },
    { key: 'merchant_name', label: 'Name', sortable: true },
    { key: 'merchant_type', label: 'Type', filterable: true },
    { key: 'contact.city', label: 'City' },
    { key: 'status', label: 'Status', filterable: true },
    { key: 'actions', label: 'Actions' }
  ],
  filters: ['merchant_type', 'status', 'city'],
  actions: ['view', 'edit', 'settings', 'delete']
}

B. Merchant Creation Form

// POST /merchants - Create new merchant
const createMerchantForm = {
  fields: {
    merchant_name: { type: 'text', required: true },
    merchant_type: { 
      type: 'select', 
      options: ['cnf', 'distributor', 'retail'],
      required: true 
    },
    parent_merchant_id: { 
      type: 'autocomplete',
      source: '/merchants', // Dynamic based on type
      required: true 
    },
    contact: {
      phone: { type: 'tel', required: true },
      email: { type: 'email', required: true },
      address_line1: { type: 'text', required: true },
      city: { type: 'text', required: true },
      state: { type: 'select', options: 'INDIAN_STATES' },
      pincode: { type: 'text', pattern: '[0-9]{6}' }
    },
    kyc: {
      gst_number: { type: 'text', pattern: 'GST_REGEX' },
      pan_number: { type: 'text', pattern: 'PAN_REGEX' }
    }
  },
  validation: 'client-side + server-side'
}

3. Merchant Settings Management

// GET /merchant-settings/{merchant_id} - Fetch settings
// PUT /merchant-settings/{merchant_id} - Update settings

const merchantSettingsForm = {
  businessSettings: {
    auto_allocate_stock: { type: 'toggle' },
    credit_limit: { type: 'currency', min: 0 },
    payment_terms_days: { type: 'number', min: 0, max: 365 }
  },
  inventorySettings: {
    low_stock_threshold: { type: 'number', min: 1 },
    enable_backorder: { type: 'toggle' },
    auto_reorder: { type: 'toggle' }
  },
  notifications: {
    email_notifications: { type: 'toggle' },
    sms_notifications: { type: 'toggle' },
    low_stock_alerts: { type: 'toggle' }
  },
  operatingHours: {
    // Dynamic day-wise hour picker
    format: { open_time: 'HH:mm', close_time: 'HH:mm', is_open: boolean }
  },
  pricing: {
    default_markup_percentage: { type: 'percentage', min: 0, max: 100 },
    allow_discount: { type: 'toggle' },
    max_discount_percentage: { type: 'percentage', min: 0, max: 50 }
  },
  taxSettings: {
    gst_rate: { type: 'percentage', default: 18 },
    inclusive_pricing: { type: 'toggle' },
    tax_exemption: { type: 'toggle' }
  }
}

4. User & Role Management

// GET /access-roles - Fetch all roles
// GET /system-users - Fetch all users
// POST /system-users - Create user

const userManagementConfig = {
  userForm: {
    username: { type: 'text', unique: true },
    email: { type: 'email', unique: true },
    full_name: { type: 'text' },
    role_id: { 
      type: 'select',
      source: '/access-roles',
      displayField: 'role_name'
    },
    merchant_id: {
      type: 'autocomplete', 
      source: '/merchants',
      filter: 'based on role permissions'
    },
    password: { type: 'password', minLength: 8 }
  },
  roleBasedAccess: {
    // Show/hide features based on user role
    'role_super_admin': 'ALL_FEATURES',
    'role_company_admin': 'EXCLUDE_DELETE_OPERATIONS', 
    'role_cnf_manager': 'REGIONAL_SCOPE_ONLY',
    'role_distributor_manager': 'LOCAL_SCOPE_ONLY',
    'role_retail_owner': 'OWN_MERCHANT_ONLY'
  }
}

πŸ”„ Key API Integration Patterns

1. Hierarchical Data Loading

// Pattern: Load parent first, then children on-demand
const loadHierarchicalData = async (parentId = null) => {
  if (!parentId) {
    // Load root level (Parent Company + cnfs)
    return await fetch(`${API_BASE_URL}/merchants?merchant_type=parent_company,cnf`)
  } else {
    // Load children of specific parent
    return await fetch(`${API_BASE_URL}/merchants/children/${parentId}`)
  }
}

// Tree expansion pattern
const expandTreeNode = async (nodeId) => {
  const children = await fetch(`${API_BASE_URL}/merchants/children/${nodeId}`)
  // Update tree state with children
}

2. Context-Aware Form Fields

// Parent selection based on merchant type
const getParentOptions = async (merchantType) => {
  const parentTypes = {
    'cnf': ['parent_company'],
    'distributor': ['cnf'], 
    'retail': ['distributor']
  }
  
  const parentType = parentTypes[merchantType]?.[0]
  if (parentType) {
    return await fetch(`${API_BASE_URL}/merchants?merchant_type=${parentType}`)
  }
}

// Settings defaults based on merchant type
const getSettingsDefaults = (merchantType) => {
  const defaults = {
    'cnf': { credit_limit: 10000000, payment_terms_days: 90, markup: 5 },
    'distributor': { credit_limit: 3000000, payment_terms_days: 60, markup: 15 },
    'retail': { credit_limit: 500000, payment_terms_days: 30, markup: 30 }
  }
  return defaults[merchantType] || {}
}

3. Error Handling & Validation

const apiErrorHandler = (error) => {
  const errorMessages = {
    400: 'Invalid request data. Please check your input.',
    401: 'Authentication required. Please login.',
    403: 'You do not have permission for this action.',
    404: 'Resource not found.',
    409: 'Duplicate entry. This record already exists.',
    422: 'Validation failed. Please check highlighted fields.',
    500: 'Server error. Please try again later.'
  }
  
  return errorMessages[error.status] || 'An unexpected error occurred.'
}

// Form validation
const validateMerchantForm = (data) => {
  const errors = {}
  
  if (!data.merchant_name?.trim()) {
    errors.merchant_name = 'Merchant name is required'
  }
  
  if (data.merchant_type === 'retail' && !data.parent_merchant_id) {
    errors.parent_merchant_id = 'Parent distributor is required for retails'
  }
  
  // GST validation for Indian businesses
  if (data.kyc?.gst_number && !/^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}Z[0-9A-Z]{1}$/.test(data.kyc.gst_number)) {
    errors['kyc.gst_number'] = 'Invalid GST number format'
  }
  
  return errors
}

🎨 UI/UX Implementation Guidelines

1. Responsive Design Requirements

/* Mobile-first approach for merchant management */
.merchant-card {
  /* Stack vertically on mobile */
  @media (max-width: 768px) {
    flex-direction: column;
  }
}

.merchant-hierarchy-tree {
  /* Horizontal scroll on mobile */
  @media (max-width: 768px) {
    overflow-x: auto;
    white-space: nowrap;
  }
}

2. State Management Pattern

// Redux/Zustand store structure
const merchantStore = {
  state: {
    merchants: [],
    selectedMerchant: null,
    hierarchyTree: {},
    filters: { type: 'all', status: 'active' },
    loading: false,
    error: null
  },
  actions: {
    fetchMerchants: async (filters) => { },
    createMerchant: async (data) => { },
    updateMerchant: async (id, data) => { },
    deleteMerchant: async (id) => { },
    setSelectedMerchant: (merchant) => { },
    setFilters: (filters) => { }
  }
}

3. Component Architecture

// Component hierarchy
const ComponentStructure = {
  'MerchantDashboard': {
    'MerchantHierarchyTree': ['TreeNode', 'TreeNodeActions'],
    'MerchantListView': ['MerchantCard', 'FilterBar', 'Pagination'],
    'MerchantFormModal': ['FormFields', 'ValidationErrors'],
    'MerchantSettingsPanel': ['SettingsSections', 'OperatingHours']
  },
  'UserManagement': {
    'UserListView': ['UserCard', 'RoleFilter'],
    'UserFormModal': ['UserForm', 'RoleSelector'],
    'PermissionsMatrix': ['RolePermissions']
  }
}

πŸ“‹ Testing Checklist

1. API Integration Tests

  • Fetch merchants hierarchy successfully
  • Create merchant with valid parent relationship
  • Update merchant settings with validation
  • Handle API errors gracefully
  • Implement proper loading states

2. UI Functionality Tests

  • Tree view expands/collapses correctly
  • Form validation works client-side
  • Filter/search functionality
  • Responsive design on mobile
  • Role-based feature visibility

3. Business Logic Tests

  • cnf can only have Parent Company as parent
  • distributor can only have cnf as parent
  • retail can only have distributor as parent
  • Credit limits are enforced based on merchant type
  • Operating hours format validation

πŸš€ Development Workflow

1. Setup & Configuration

# Start the API server
uvicorn app.main:app --reload --port 8000

# Access API documentation
open http://localhost:8000/docs

# Test API endpoints
curl -X GET "http://localhost:8000/merchants" -H "Content-Type: application/json"

2. Implementation Order

  1. Phase 1: Basic merchant CRUD operations
  2. Phase 2: Hierarchy tree view and navigation
  3. Phase 3: Merchant settings management
  4. Phase 4: User and role management
  5. Phase 5: Advanced features (reports, analytics)

3. Data Flow Examples

// Example: Creating a new retail
const createretail = async (retailData) => {
  // 1. Validate form data
  const errors = validateMerchantForm(retailData)
  if (Object.keys(errors).length > 0) {
    return { success: false, errors }
  }
  
  // 2. Call API
  const response = await fetch(`${API_BASE_URL}/merchants`, {
    method: 'POST',
    headers: apiHeaders,
    body: JSON.stringify({...retailData, merchant_type: 'retail'})
  })
  
  // 3. Handle response
  if (response.ok) {
    const newretail = await response.json()
    // Update local state
    addMerchantToStore(newretail)
    // Create default settings
    await createDefaultSettings(newretail.merchant_id)
    return { success: true, data: newretail }
  } else {
    const error = await response.json()
    return { success: false, error: error.detail }
  }
}

πŸ”§ Common Implementation Patterns

1. Autocomplete for Parent Selection

const ParentMerchantSelector = ({ merchantType, value, onChange }) => {
  const [options, setOptions] = useState([])
  
  useEffect(() => {
    const loadParentOptions = async () => {
      const parentType = getParentType(merchantType)
      const response = await fetch(`${API_BASE_URL}/merchants?merchant_type=${parentType}`)
      setOptions(await response.json())
    }
    
    if (merchantType) {
      loadParentOptions()
    }
  }, [merchantType])
  
  return (
    <Autocomplete
      options={options}
      getOptionLabel={(option) => `${option.merchant_name} (${option.merchant_code})`}
      value={value}
      onChange={onChange}
      placeholder="Select parent merchant..."
    />
  )
}

2. Operating Hours Component

const OperatingHoursEditor = ({ value, onChange }) => {
  const days = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']
  
  return (
    <div className="operating-hours-grid">
      {days.map(day => (
        <div key={day} className="day-row">
          <label>{day.charAt(0).toUpperCase() + day.slice(1)}</label>
          <input 
            type="checkbox"
            checked={value[day]?.is_open || false}
            onChange={(e) => onChange(day, 'is_open', e.target.checked)}
          />
          {value[day]?.is_open && (
            <>
              <input 
                type="time"
                value={value[day]?.open_time || '09:00'}
                onChange={(e) => onChange(day, 'open_time', e.target.value)}
              />
              <input 
                type="time"
                value={value[day]?.close_time || '18:00'} 
                onChange={(e) => onChange(day, 'close_time', e.target.value)}
              />
            </>
          )}
        </div>
      ))}
    </div>
  )
}

This prompt provides comprehensive guidance for building a production-ready UI that integrates seamlessly with your hierarchical merchant API system.