Files
nutriscan/lib/searchUtils.ts
evandro bf688257ef refactor(api): extrair montagem e paginação da busca para lib/offSearch
GET /api/search passa de CC 41 para <= 10. Testes de caracterização
(sem rede: fetch e cache JSON temporário) cobrem validação, filtros,
ordenação, paginação, modo cache-only e erros.

Também: parameter property de NutriScanError virou campo explícito e
imports só de tipo usam import type, para o type stripping nativo do
Node; o script de teste não usa mais --experimental-transform-types
(removida no Node 26).
2026-10-10 04:14:48 -03:00

54 lines
1.3 KiB
TypeScript

import type { Product } from "./openFoodFactsApi";
/**
* Calcula score de relevância de um produto em relação à query
*/
export function calculateRelevanceScore(
product: Product,
searchTerm: string
): number {
const productName = product.product_name?.toLowerCase() || "";
const lowerSearchTerm = searchTerm.toLowerCase();
// Nome exato = maior prioridade
if (productName === lowerSearchTerm) {
return 3;
}
// Nome começa com a query = alta prioridade
if (productName.startsWith(lowerSearchTerm)) {
return 2;
}
// Nome contém a query = média prioridade
if (productName.includes(lowerSearchTerm)) {
return 1;
}
// Correspondência em marca ou categoria = baixa prioridade
if (
product.brands?.toLowerCase().includes(lowerSearchTerm) ||
product.categories?.toLowerCase().includes(lowerSearchTerm)
) {
return 0.5;
}
return 0;
}
/**
* Ordena produtos por relevância em relação à query
*/
export function sortByRelevance(
products: Product[],
searchTerm: string
): Product[] {
return products
.map((product) => ({
product,
relevanceScore: calculateRelevanceScore(product, searchTerm),
}))
.sort((a, b) => b.relevanceScore - a.relevanceScore)
.map(({ product }) => product);
}