PredictiveSearch pasa de filtrar en memoria el arreglo completo de productos (prop products, substring match) a un fetch debounced (250ms, con AbortController) contra la nueva ruta /api/search -- mismo componente visual, solo cambia de donde salen los datos, tal como pide el ADR 0006 seccion 5. /api/search (nueva, server-side) es el puente same-origin: el componente es cliente y no puede pegarle directo al provider server-side (MEDUSA_BACKEND_URL es DNS interno del cluster, no resuelve desde el navegador). CatalogProvider gana un metodo OPCIONAL searchWithFacets? (no cambia la firma de getProducts/searchProducts) -- mock.ts y shopify.ts compilan sin tocarlos, siguen sin implementarlo. medusa.ts lo implementa contra /store/search (Fase 2), reutilizando mapProduct() ya que la ruta devuelve el mismo shape de producto que /store/products. searchProducts tambien se repunta a /store/search, dejando de usar el ?q= + re-filtro client-side de fetchProducts/matchesFilters para busqueda (que sigue sirviendo para navegacion sin busqueda, sin cambios). Navbar deja de pasarle products a PredictiveSearch (ya no los necesita) pero los sigue recibiendo el mismo -- collections todavia se deriva de ahi. Limpieza: borrado patches/frontend-medusa-env.yaml, confirmado huerfano (ningun kustomization lo referencia; el patch que si esta vivo es frontend/patches/deployment.yaml). Validado: build completo de Docker (target builder) -- npm ci, next build con typecheck, /api/search aparece en la tabla de rutas generada. Cero errores nuevos (los warnings de ESLint son preexistentes en catalog-client.tsx, no tocado en esta fase).
44 lines
1.5 KiB
TypeScript
44 lines
1.5 KiB
TypeScript
import { searchWithFacets } from "@/lib/headless/client";
|
|
import type { ProductFilters } from "@/lib/headless/types";
|
|
|
|
// PredictiveSearch es un componente cliente y no puede pegarle directo
|
|
// al provider server-side (MEDUSA_BACKEND_URL es un nombre DNS interno
|
|
// del cluster, no resuelve desde el navegador) -- esta ruta es el
|
|
// puente same-origin.
|
|
export async function GET(request: Request) {
|
|
const { searchParams } = new URL(request.url);
|
|
|
|
const filters: ProductFilters = {
|
|
query: searchParams.get("q") ?? undefined,
|
|
category: searchParams.get("category") ?? undefined,
|
|
collection: searchParams.get("collection") ?? undefined,
|
|
brand: searchParams.get("brand") ?? undefined,
|
|
ageRange: searchParams.get("ageRange") ?? undefined,
|
|
};
|
|
|
|
const minPrice = searchParams.get("minPrice");
|
|
if (minPrice) filters.minPrice = Number(minPrice);
|
|
const maxPrice = searchParams.get("maxPrice");
|
|
if (maxPrice) filters.maxPrice = Number(maxPrice);
|
|
|
|
try {
|
|
const result = await searchWithFacets(filters);
|
|
// provider actual no implementa searchWithFacets (mock/shopify) --
|
|
// degradar a vacío, no a 500; el componente cliente cae de nuevo a
|
|
// su propio filtrado si esta ruta no trae nada útil.
|
|
return Response.json(
|
|
result ?? { products: [], facetDistribution: {}, count: 0 },
|
|
);
|
|
} catch (error) {
|
|
return Response.json(
|
|
{
|
|
products: [],
|
|
facetDistribution: {},
|
|
count: 0,
|
|
error: (error as Error).message,
|
|
},
|
|
{ status: 502 },
|
|
);
|
|
}
|
|
}
|