Skip to main content

E-Commerce Search Engine

Author: Josh S. Sakweli, Backend Lead Team Last Updated: 2025-12-30 Version: v1.0

Base URL: https://api.nextgate.com/api/v1

Short Description: Public search endpoints for discovering shops, products, and active purchase groups on the Nexgate e-commerce platform. These endpoints power the main search functionality, product discovery, and group buying features across the application.

Hints:

  • Search query must be at least 2 characters
  • Results are ordered alphabetically by name
  • Filter by type using the type parameter: SHOP, PRODUCT, or PURCHASE_GROUP
  • Purchase groups are searched by both name and group code (e.g., GP-ABC123)
  • All endpoints are public and do not require authentication
  • Maximum page size is 50 results
  • Rate limiting applies to prevent abuse

Standard Response Format

All API responses follow a consistent structure using our Globe Response Builder pattern:

Success Response Structure

{
  "success": true,
  "httpStatus": "OK",
  "message": "Operation completed successfully",
  "action_time": "2025-12-30T10:30:45",
  "data": {
    // Actual response data goes here
  }
}

Error Response Structure

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Error description",
  "action_time": "2025-12-30T10:30:45",
  "data": null
}

Search Result Types

Each search result contains a type field indicating the result category:

Type Description Specific Fields
SHOP Active shop/store shop object
PRODUCT Active product product object
PURCHASE_GROUP Open group purchase purchaseGroup object

Endpoints


Purpose: Search across all types (shops, products, and purchase groups) with optional type filtering

Endpoint: GET {base_url}/api/v1/e-commerce/search

Access Level: 🌐 Public (No Authentication Required)

Query Parameters:

Parameter Type Required Default Description Validation
query string Yes - Search term Min 2 characters
type string No null (all) Filter by type SHOP, PRODUCT, PURCHASE_GROUP
page int No 1 Page number Min 1
size int No 20 Results per page Max 50

Request Examples:

# Search all types
GET /api/v1/e-commerce/search?query=iphone&page=1&size=20

# Search shops only
GET /api/v1/e-commerce/search?query=fashion&type=SHOP

# Search products only
GET /api/v1/e-commerce/search?query=dress&type=PRODUCT

# Search purchase groups only
GET /api/v1/e-commerce/search?query=GP-ABC123&type=PURCHASE_GROUP

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Search results retrieved successfully",
  "action_time": "2025-12-30T10:30:45",
  "data": {
    "content": [
      {
        "type": "SHOP",
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "Fashion Hub TZ",
        "imageUrl": "https://storage.example.com/shops/logo1.jpg",
        "shop": {
          "slug": "fashion-hub-tz",
          "isVerified": true,
          "rating": 4.8,
          "productsCount": 156,
          "location": "Dar es Salaam"
        }
      },
      {
        "type": "PRODUCT",
        "id": "660e8400-e29b-41d4-a716-446655440001",
        "name": "Summer Fashion Dress",
        "imageUrl": "https://storage.example.com/products/dress1.jpg",
        "product": {
          "slug": "summer-fashion-dress",
          "price": 45000.00,
          "discountPrice": 38000.00,
          "currency": "TZS",
          "inStock": true,
          "rating": 4.5,
          "shopName": "Fashion Hub TZ",
          "shopIsVerified": true
        }
      },
      {
        "type": "PURCHASE_GROUP",
        "id": "770e8400-e29b-41d4-a716-446655440002",
        "name": "Fashion Week Special Deal",
        "imageUrl": "https://storage.example.com/products/bundle.jpg",
        "purchaseGroup": {
          "groupCode": "GP-FWS123",
          "regularPrice": 150000.00,
          "groupPrice": 120000.00,
          "savingsPercentage": 20,
          "seatsRemaining": 3,
          "totalSeats": 10,
          "expiresAt": "2025-12-31T23:59:59",
          "shopName": "Fashion Hub TZ"
        }
      }
    ],
    "page": 0,
    "size": 20,
    "totalElements": 3,
    "totalPages": 1,
    "hasNext": false,
    "hasPrevious": false,
    "shopsCount": 1,
    "productsCount": 1,
    "purchaseGroupsCount": 1
  }
}

Response Fields:

Field Type Description
content array List of search result items
page int Current page number (0-indexed)
size int Page size
totalElements long Total number of results
totalPages int Total number of pages
hasNext boolean Whether more pages exist
hasPrevious boolean Whether previous pages exist
shopsCount long Total shops matching query
productsCount long Total products matching query
purchaseGroupsCount long Total purchase groups matching query

Error Response JSON Samples:

Query too short:

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Search query must be at least 2 characters",
  "action_time": "2025-12-30T10:30:45",
  "data": null
}

Invalid type:

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Invalid type. Must be: SHOP, PRODUCT, or PURCHASE_GROUP",
  "action_time": "2025-12-30T10:30:45",
  "data": null
}

2. Search Shops

Purpose: Search for active shops by name

Endpoint: GET {base_url}/api/v1/e-commerce/search/shops

Access Level: 🌐 Public (No Authentication Required)

Query Parameters:

Parameter Type Required Default Description Validation
query string Yes - Shop name search term Min 2 characters
page int No 1 Page number Min 1
size int No 20 Results per page Max 50

Request Example:

GET /api/v1/e-commerce/search/shops?query=fashion&page=1&size=20

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Shops retrieved successfully",
  "action_time": "2025-12-30T10:30:45",
  "data": {
    "content": [
      {
        "type": "SHOP",
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "Fashion Hub TZ",
        "imageUrl": "https://storage.example.com/shops/logo1.jpg",
        "shop": {
          "slug": "fashion-hub-tz",
          "isVerified": true,
          "rating": 4.8,
          "productsCount": 156,
          "location": "Dar es Salaam"
        }
      },
      {
        "type": "SHOP",
        "id": "660e8400-e29b-41d4-a716-446655440001",
        "name": "Fashion Zone",
        "imageUrl": "https://storage.example.com/shops/logo2.jpg",
        "shop": {
          "slug": "fashion-zone",
          "isVerified": false,
          "rating": 4.2,
          "productsCount": 89,
          "location": "Arusha"
        }
      }
    ],
    "page": 0,
    "size": 20,
    "totalElements": 2,
    "totalPages": 1,
    "hasNext": false,
    "hasPrevious": false,
    "shopsCount": 2,
    "productsCount": 0,
    "purchaseGroupsCount": 0
  }
}

Shop Info Fields:

Field Type Description
slug string URL-friendly shop identifier
isVerified boolean Whether shop is verified
rating double Shop rating (0-5)
productsCount int Number of active products
location string Shop location

3. Search Products

Purpose: Search for active products by name

Endpoint: GET {base_url}/api/v1/e-commerce/search/products

Access Level: 🌐 Public (No Authentication Required)

Query Parameters:

Parameter Type Required Default Description Validation
query string Yes - Product name search term Min 2 characters
page int No 1 Page number Min 1
size int No 20 Results per page Max 50

Request Example:

GET /api/v1/e-commerce/search/products?query=dress&page=1&size=20

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Products retrieved successfully",
  "action_time": "2025-12-30T10:30:45",
  "data": {
    "content": [
      {
        "type": "PRODUCT",
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "Summer Dress Collection",
        "imageUrl": "https://storage.example.com/products/dress1.jpg",
        "product": {
          "slug": "summer-dress-collection",
          "price": 45000.00,
          "discountPrice": 38000.00,
          "currency": "TZS",
          "inStock": true,
          "rating": 4.5,
          "shopName": "Fashion Hub TZ",
          "shopIsVerified": true
        }
      },
      {
        "type": "PRODUCT",
        "id": "660e8400-e29b-41d4-a716-446655440001",
        "name": "Evening Dress",
        "imageUrl": "https://storage.example.com/products/dress2.jpg",
        "product": {
          "slug": "evening-dress",
          "price": 85000.00,
          "discountPrice": null,
          "currency": "TZS",
          "inStock": true,
          "rating": 4.8,
          "shopName": "Elegance Store",
          "shopIsVerified": true
        }
      },
      {
        "type": "PRODUCT",
        "id": "770e8400-e29b-41d4-a716-446655440002",
        "name": "Casual Dress",
        "imageUrl": "https://storage.example.com/products/dress3.jpg",
        "product": {
          "slug": "casual-dress",
          "price": 35000.00,
          "discountPrice": 30000.00,
          "currency": "TZS",
          "inStock": false,
          "rating": 4.0,
          "shopName": "Budget Fashion",
          "shopIsVerified": false
        }
      }
    ],
    "page": 0,
    "size": 20,
    "totalElements": 3,
    "totalPages": 1,
    "hasNext": false,
    "hasPrevious": false,
    "shopsCount": 0,
    "productsCount": 3,
    "purchaseGroupsCount": 0
  }
}

Product Info Fields:

Field Type Description
slug string URL-friendly product identifier
price decimal Regular price
discountPrice decimal Discounted price (null if no discount)
currency string Price currency (e.g., TZS)
inStock boolean Whether product is in stock
rating double Product rating (0-5)
shopName string Name of the shop selling this product
shopIsVerified boolean Whether the shop is verified

4. Search Purchase Groups

Purpose: Search for active (open, non-expired) purchase groups by name or group code

Endpoint: GET {base_url}/api/v1/e-commerce/search/groups

Access Level: 🌐 Public (No Authentication Required)

Query Parameters:

Parameter Type Required Default Description Validation
query string Yes - Group name or code Min 2 characters
page int No 1 Page number Min 1
size int No 20 Results per page Max 50

Request Examples:

# Search by group name
GET /api/v1/e-commerce/search/groups?query=iPhone Deal&page=1&size=20

# Search by group code
GET /api/v1/e-commerce/search/groups?query=GP-ABC123&page=1&size=20

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Purchase groups retrieved successfully",
  "action_time": "2025-12-30T10:30:45",
  "data": {
    "content": [
      {
        "type": "PURCHASE_GROUP",
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "iPhone 15 Pro - Dar es Salaam Deal",
        "imageUrl": "https://storage.example.com/products/iphone15.jpg",
        "purchaseGroup": {
          "groupCode": "GP-ABC123",
          "regularPrice": 2500000.00,
          "groupPrice": 2200000.00,
          "savingsPercentage": 12,
          "seatsRemaining": 2,
          "totalSeats": 5,
          "expiresAt": "2025-12-31T08:00:00",
          "shopName": "TechZone TZ"
        }
      },
      {
        "type": "PURCHASE_GROUP",
        "id": "660e8400-e29b-41d4-a716-446655440001",
        "name": "iPhone 15 Plus Group Buy",
        "imageUrl": "https://storage.example.com/products/iphone15plus.jpg",
        "purchaseGroup": {
          "groupCode": "GP-XYZ789",
          "regularPrice": 2200000.00,
          "groupPrice": 1950000.00,
          "savingsPercentage": 11,
          "seatsRemaining": 4,
          "totalSeats": 8,
          "expiresAt": "2025-12-30T18:00:00",
          "shopName": "Mobile World"
        }
      }
    ],
    "page": 0,
    "size": 20,
    "totalElements": 2,
    "totalPages": 1,
    "hasNext": false,
    "hasPrevious": false,
    "shopsCount": 0,
    "productsCount": 0,
    "purchaseGroupsCount": 2
  }
}

Purchase Group Info Fields:

Field Type Description
groupCode string Unique group code (e.g., GP-ABC123)
regularPrice decimal Original product price
groupPrice decimal Discounted group price
savingsPercentage int Percentage saved
seatsRemaining int Available seats
totalSeats int Total seats in group
expiresAt datetime Group expiration time
shopName string Name of the shop

Note: Only returns groups that are:

  • Status: OPEN
  • Not expired (expiresAt > now)
  • Not deleted

Endpoints Summary

# Method Endpoint Purpose
1 GET /api/v1/e-commerce/search Search all types
2 GET /api/v1/e-commerce/search/shops Search shops only
3 GET /api/v1/e-commerce/search/products Search products only
4 GET /api/v1/e-commerce/search/groups Search purchase groups only

Common Error Responses

Status Message Cause
400 BAD_REQUEST Search query must be at least 2 characters Query too short
400 BAD_REQUEST Invalid type. Must be: SHOP, PRODUCT, or PURCHASE_GROUP Invalid type parameter
429 TOO_MANY_REQUESTS Rate limit exceeded Too many requests

Frontend Usage Examples

JavaScript/TypeScript

// Global search
const searchAll = async (query, page = 1, size = 20) => {
  const response = await fetch(
    `/api/v1/e-commerce/search?query=${encodeURIComponent(query)}&page=${page}&size=${size}`
  );
  return response.json();
};

// Search with type filter
const searchByType = async (query, type, page = 1) => {
  const response = await fetch(
    `/api/v1/e-commerce/search?query=${encodeURIComponent(query)}&type=${type}&page=${page}`
  );
  return response.json();
};

// Search shops only
const searchShops = async (query) => {
  const response = await fetch(
    `/api/v1/e-commerce/search/shops?query=${encodeURIComponent(query)}`
  );
  return response.json();
};

// Search products only
const searchProducts = async (query) => {
  const response = await fetch(
    `/api/v1/e-commerce/search/products?query=${encodeURIComponent(query)}`
  );
  return response.json();
};

// Search groups by name or code
const searchGroups = async (query) => {
  const response = await fetch(
    `/api/v1/e-commerce/search/groups?query=${encodeURIComponent(query)}`
  );
  return response.json();
};

Rendering Results

const renderResults = (results) => {
  results.content.forEach(item => {
    switch (item.type) {
      case 'SHOP':
        renderShopCard(item);
        break;
      case 'PRODUCT':
        renderProductCard(item);
        break;
      case 'PURCHASE_GROUP':
        renderGroupCard(item);
        break;
    }
  });
  
  // Show counts
  console.log(`Found: ${results.shopsCount} shops, ${results.productsCount} products, ${results.purchaseGroupsCount} groups`);
};

5. Get Product Details by ID

Purpose: Retrieve detailed product information by product ID for public viewing

Endpoint: GET {base_url}/api/v1/e-commerce/search/id/{productId}

Access Level: 🌐 Public (No Authentication Required)

Path Parameters:

ParameterTypeRequiredDescriptionValidation
productIdUUIDYesUnique product identifierValid UUID format

Request Example:

GET /api/v1/e-commerce/search/id/550e8400-e29b-41d4-a716-446655440000

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Product retrieved successfully",
  "action_time": "2025-12-30T10:30:45",
  "data": {
    "productId": "550e8400-e29b-41d4-a716-446655440000",
    "productName": "iPhone 15 Pro Max",
    "productSlug": "iphone-15-pro-max",
    "productDescription": "The latest iPhone with advanced features, A17 Pro chip, and titanium design.",
    "shortDescription": "Latest iPhone with A17 Pro chip",
    "productImages": [
      "https://storage.example.com/products/iphone15-1.jpg",
      "https://storage.example.com/products/iphone15-2.jpg",
      "https://storage.example.com/products/iphone15-3.jpg"
    ],
    "price": 2500000.00,
    "comparePrice": 2800000.00,
    "discountPercentage": 10.71,
    "isOnSale": true,
    "stockQuantity": 25,
    "lowStockThreshold": 5,
    "isInStock": true,
    "isLowStock": false,
    "trackInventory": true,
    "brand": "Apple",
    "sku": "IPHONE15PM-256-BLK",
    "condition": "NEW",
    "status": "ACTIVE",
    "tags": ["smartphone", "apple", "iphone", "5g"],
    "metaTitle": "iPhone 15 Pro Max - Buy Online",
    "metaDescription": "Buy the latest iPhone 15 Pro Max with free shipping",
    "shopId": "660e8400-e29b-41d4-a716-446655440001",
    "shopName": "TechZone TZ",
    "shopSlug": "techzone-tz",
    "categoryId": "770e8400-e29b-41d4-a716-446655440002",
    "categoryName": "Smartphones",
    "isFeatured": true,
    "isDigital": false,
    "requiresShipping": true,
    "createdAt": "2025-12-01T08:00:00",
    "updatedAt": "2025-12-30T10:00:00",
    "specifications": {
      "Display": "6.7-inch Super Retina XDR",
      "Chip": "A17 Pro",
      "Storage": "256GB",
      "Camera": "48MP Main + 12MP Ultra Wide + 12MP Telephoto",
      "Battery": "4422 mAh",
      "5G": "Yes"
    },
    "hasSpecifications": true,
    "specificationCount": 6,
    "colors": [
      {
        "name": "Natural Titanium",
        "hex": "#9A9A98",
        "images": ["https://storage.example.com/products/iphone15-titanium.jpg"],
        "priceAdjustment": 0.00,
        "finalPrice": 2500000.00,
        "hasExtraFee": false,
        "extraFeeReason": null
      },
      {
        "name": "Blue Titanium",
        "hex": "#394C5F",
        "images": ["https://storage.example.com/products/iphone15-blue.jpg"],
        "priceAdjustment": 50000.00,
        "finalPrice": 2550000.00,
        "hasExtraFee": true,
        "extraFeeReason": "Limited edition color"
      }
    ],
    "hasMultipleColors": true,
    "colorCount": 2,
    "priceRange": {
      "minPrice": 2500000.00,
      "maxPrice": 2550000.00,
      "priceStartsFrom": 2500000.00,
      "hasPriceVariations": true
    },
    "orderingLimits": {
      "minOrderQuantity": 1,
      "maxOrderQuantity": 5,
      "canOrderQuantity": 5,
      "maxAllowedQuantity": 5,
      "hasOrderingLimits": true
    },
    "groupBuying": {
      "isEnabled": true,
      "maxGroupSize": 5,
      "groupPrice": 2200000.00,
      "groupDiscount": 300000.00,
      "groupDiscountPercentage": 12.00,
      "timeLimitHours": 48,
      "canJoinGroup": true
    },
    "installmentOptions": {
      "isEnabled": true,
      "isAvailable": true,
      "downPaymentRequired": true,
      "minDownPaymentPercentage": 20.00,
      "plans": [
        {
          "planId": "3-months",
          "duration": 3,
          "interval": "MONTHLY",
          "interestRate": 0.00,
          "description": "3 months interest-free",
          "calculations": {
            "downPayment": 500000.00,
            "remainingAmount": 2000000.00,
            "totalInterest": 0.00,
            "paymentAmount": 666667.00,
            "totalAmount": 2500000.00
          },
          "paymentSchedule": [
            {
              "paymentNumber": 1,
              "amount": 666667.00,
              "dueDate": "2026-01-30T10:30:45",
              "description": "Payment 1 of 3"
            },
            {
              "paymentNumber": 2,
              "amount": 666667.00,
              "dueDate": "2026-02-28T10:30:45",
              "description": "Payment 2 of 3"
            },
            {
              "paymentNumber": 3,
              "amount": 666666.00,
              "dueDate": "2026-03-30T10:30:45",
              "description": "Payment 3 of 3"
            }
          ],
          "isPopular": true
        },
        {
          "planId": "6-months",
          "duration": 6,
          "interval": "MONTHLY",
          "interestRate": 5.00,
          "description": "6 months with 5% interest",
          "calculations": {
            "downPayment": 500000.00,
            "remainingAmount": 2000000.00,
            "totalInterest": 100000.00,
            "paymentAmount": 350000.00,
            "totalAmount": 2600000.00
          },
          "isPopular": false
        }
      ],
      "eligibilityStatus": "ELIGIBLE",
      "creditCheckRequired": false
    },
    "purchaseOptions": {
      "canBuyNow": true,
      "canJoinGroup": true,
      "canPayInstallment": true,
      "recommendedOption": "GROUP_BUYING",
      "bestDeal": {
        "option": "GROUP_BUYING",
        "savings": 300000.00,
        "finalPrice": 2200000.00
      }
    }
  }
}

Response Fields:

Basic Information

FieldTypeDescription
productIdUUIDUnique product identifier
productNamestringProduct name
productSlugstringURL-friendly product identifier
productDescriptionstringFull product description
shortDescriptionstringShort product summary
productImagesarrayList of product image URLs

Pricing Information

FieldTypeDescription
pricedecimalCurrent selling price
comparePricedecimalOriginal/compare price
discountPercentagedecimalDiscount percentage
isOnSalebooleanWhether product is on sale

Inventory Information

FieldTypeDescription
stockQuantityintAvailable stock
lowStockThresholdintLow stock alert threshold
isInStockbooleanWhether product is in stock
isLowStockbooleanWhether stock is low
trackInventorybooleanWhether inventory is tracked

Product Details

FieldTypeDescription
brandstringProduct brand
skustringStock keeping unit
conditionenumNEW, USED, REFURBISHED
statusenumACTIVE, INACTIVE, DRAFT

Shop & Category

FieldTypeDescription
shopIdUUIDShop identifier
shopNamestringShop name
shopSlugstringShop URL slug
categoryIdUUIDCategory identifier
categoryNamestringCategory name

Specifications

FieldTypeDescription
specificationsobjectKey-value pairs of product specs
hasSpecificationsbooleanWhether product has specs
specificationCountintNumber of specifications

Colors

FieldTypeDescription
colorsarrayAvailable color options
colors[].namestringColor name
colors[].hexstringHex color code
colors[].imagesarrayColor-specific images
colors[].priceAdjustmentdecimalPrice adjustment for color
colors[].finalPricedecimalFinal price with adjustment
colors[].hasExtraFeebooleanWhether color has extra fee
hasMultipleColorsbooleanWhether multiple colors exist
colorCountintNumber of color options

Price Range

FieldTypeDescription
priceRange.minPricedecimalMinimum price across variants
priceRange.maxPricedecimalMaximum price across variants
priceRange.priceStartsFromdecimalStarting price
priceRange.hasPriceVariationsbooleanWhether prices vary

Ordering Limits

FieldTypeDescription
orderingLimits.minOrderQuantityintMinimum order quantity
orderingLimits.maxOrderQuantityintMaximum order quantity
orderingLimits.canOrderQuantityintQuantity user can order
orderingLimits.hasOrderingLimitsbooleanWhether limits apply

Group Buying

FieldTypeDescription
groupBuying.isEnabledbooleanWhether group buying is enabled
groupBuying.maxGroupSizeintMaximum group participants
groupBuying.groupPricedecimalGroup purchase price
groupBuying.groupDiscountdecimalSavings amount
groupBuying.groupDiscountPercentagedecimalSavings percentage
groupBuying.timeLimitHoursintHours to fill group
groupBuying.canJoinGroupbooleanWhether user can join

Installment Options

FieldTypeDescription
installmentOptions.isEnabledbooleanWhether installments enabled
installmentOptions.isAvailablebooleanWhether available for product
installmentOptions.downPaymentRequiredbooleanWhether down payment needed
installmentOptions.minDownPaymentPercentagedecimalMinimum down payment %
installmentOptions.plansarrayAvailable payment plans
installmentOptions.eligibilityStatusstringUser eligibility status

Purchase Options Summary

FieldTypeDescription
purchaseOptions.canBuyNowbooleanCan purchase immediately
purchaseOptions.canJoinGroupbooleanCan join group purchase
purchaseOptions.canPayInstallmentbooleanCan use installments
purchaseOptions.recommendedOptionstringBest option for user
purchaseOptions.bestDeal.optionstringBest deal type
purchaseOptions.bestDeal.savingsdecimalAmount saved
purchaseOptions.bestDeal.finalPricedecimalFinal price with deal

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Product not found",
  "action_time": "2025-12-30T10:30:45",
  "data": null
}

Standard Error Types:

StatusMessageCause
404 NOT_FOUNDProduct not foundInvalid product ID
400 BAD_REQUESTInvalid product ID formatMalformed UUID

Endpoints Summary (Updated)

#MethodEndpointPurpose
1GET/api/v1/e-commerce/searchSearch all types
2GET/api/v1/e-commerce/search/shopsSearch shops only
3GET/api/v1/e-commerce/search/productsSearch products only
4GET/api/v1/e-commerce/search/groupsSearch purchase groups only
5GET/api/v1/e-commerce/search/id/{productId}Get product details by ID

Frontend Usage Example

// Get full product details after search result click
const getProductDetails = async (productId) => {
  const response = await fetch(
    `/api/v1/e-commerce/search/id/${productId}`
  );
  return response.json();
};

// Usage
const handleSearchResultClick = async (item) => {
  if (item.type === 'PRODUCT') {
    const productDetails = await getProductDetails(item.id);
    showProductModal(productDetails.data);
  }
};