func()

in src/psearch/serving/internal/services/spanner_service.go [261:443]


func (s *SpannerService) transformToSearchResult(productID string, productData map[string]interface{}, score float64) (models.SearchResult, error) {
	// Create score map
	scoreMap := map[string]float64{
		"hybrid": score,
	}

	// Extract name
	name, _ := productData["name"].(string)
	
	// Extract title
	title, _ := productData["title"].(string)

	// Extract brands
	var brands []string
	if brandsData, ok := productData["brands"].([]interface{}); ok {
		for _, b := range brandsData {
			if brand, ok := b.(string); ok {
				brands = append(brands, brand)
			}
		}
	}

	// Extract categories
	var categories []string
	if categoriesData, ok := productData["categories"].([]interface{}); ok {
		for _, c := range categoriesData {
			if category, ok := c.(string); ok {
				categories = append(categories, category)
			}
		}
	}

	// Handle price info
	priceInfo := models.PriceInfo{
		CurrencyCode: "USD", // Default
	}
	if priceInfoData, ok := productData["priceInfo"].(map[string]interface{}); ok {
		if cost, ok := priceInfoData["cost"].(string); ok {
			priceInfo.Cost = cost
		}
		if currencyCode, ok := priceInfoData["currencyCode"].(string); ok {
			priceInfo.CurrencyCode = currencyCode
		}
		if originalPrice, ok := priceInfoData["originalPrice"].(string); ok {
			priceInfo.OriginalPrice = originalPrice
		}
		if price, ok := priceInfoData["price"].(string); ok {
			priceInfo.Price = price
		}
		if effectiveTime, ok := priceInfoData["priceEffectiveTime"].(string); ok {
			priceInfo.PriceEffectiveTime = effectiveTime
		}
		if expireTime, ok := priceInfoData["priceExpireTime"].(string); ok {
			priceInfo.PriceExpireTime = expireTime
		}
	}

	// Handle images
	var images []models.Image
	if imagesData, ok := productData["images"].([]interface{}); ok {
		for _, img := range imagesData {
			if imgMap, ok := img.(map[string]interface{}); ok {
				height := "0"
				width := "0"
				uri := ""

				if h, ok := imgMap["height"].(string); ok {
					height = h
				}
				if w, ok := imgMap["width"].(string); ok {
					width = w
				}
				if u, ok := imgMap["uri"].(string); ok {
					uri = u
				}

				// Convert gs:// URLs to https://storage.googleapis.com/
				if len(uri) > 5 && uri[:5] == "gs://" {
					uri = "https://storage.googleapis.com/" + uri[5:]
				}

				images = append(images, models.Image{
					Height: height,
					Width:  width,
					URI:    uri,
				})
			}
		}
	}

	// Extract sizes
	var sizes []string
	if sizesData, ok := productData["sizes"].([]interface{}); ok {
		for _, s := range sizesData {
			if size, ok := s.(string); ok {
				sizes = append(sizes, size)
			} else if sizeNum, ok := s.(float64); ok {
				sizes = append(sizes, fmt.Sprintf("%v", sizeNum))
			}
		}
	}

	// Extract URI
	uri, _ := productData["uri"].(string)

	// Process attributes
	var attributes []models.Attribute
	if attrsData, ok := productData["attributes"].([]interface{}); ok {
		for _, attr := range attrsData {
			if attrMap, ok := attr.(map[string]interface{}); ok {
				key, keyOk := attrMap["key"].(string)
				valueData, valueOk := attrMap["value"].(map[string]interface{})
				
				if keyOk && valueOk {
					// Handle attribute value
					attrValue := models.AttributeValue{}
					
					if textData, ok := valueData["text"].([]interface{}); ok {
						for _, t := range textData {
							if textStr, ok := t.(string); ok {
								attrValue.Text = append(attrValue.Text, textStr)
							}
						}
					}

					if numbersData, ok := valueData["numbers"].([]interface{}); ok {
						for _, n := range numbersData {
							if num, ok := n.(float64); ok {
								attrValue.Numbers = append(attrValue.Numbers, num)
							}
						}
					}

					if indexable, ok := valueData["indexable"].(string); ok {
						attrValue.Indexable = &indexable
					}

					if searchable, ok := valueData["searchable"].(string); ok {
						attrValue.Searchable = &searchable
					}

					attributes = append(attributes, models.Attribute{
						Key:   key,
						Value: attrValue,
					})
				}
			}
		}
	}

	// Handle tags as attributes
	if tagsData, ok := productData["tags"].([]interface{}); ok {
		for _, t := range tagsData {
			if tag, ok := t.(string); ok {
				attributes = append(attributes, models.Attribute{
					Key: "tag",
					Value: models.AttributeValue{
						Text: []string{tag},
					},
				})
			}
		}
	}

	// Create search result
	result := models.SearchResult{
		ID:                productID,
		Name:              name,
		Title:             title,
		Brands:            brands,
		Categories:        categories,
		PriceInfo:         priceInfo,
		Availability:      "IN_STOCK", // Default
		Images:            images,
		Sizes:             sizes,
		RetrievableFields: "*",
		Attributes:        attributes,
		URI:               uri,
		Score:             scoreMap,
	}

	return result, nil
}