TypeScript 50.6%
JavaScript 46.1%
SQL 2.1%
Shell 0.6%
CSS 0.5%
1// Recherche unifiée : base canonique (annonces agrégées) + publications directes Toveli, un seul contrat de résultat.2import { searchListings as searchAggregated, mapPoints as aggPoints } from "./queries";3import { searchDirect } from "./listings/public";4import type { SearchParams, SearchResult, ListingCard } from "./types";56function sortCards(items: ListingCard[], sort: SearchParams["sort"]) {7 const k = sort ?? "recent";8 return items.sort((a, b) => k === "price_asc" ? (a.price ?? 0) - (b.price ?? 0) : k === "price_desc" ? (b.price ?? 0) - (a.price ?? 0) : k === "area_desc" ? (b.areaSqft ?? 0) - (a.areaSqft ?? 0) : k === "deal" ? ((b.ratio ?? -1) - (a.ratio ?? -1)) : (Date.parse(b.firstSeen ?? "") || 0) - (Date.parse(a.firstSeen ?? "") || 0));9}10export async function unifiedSearch(p: SearchParams): Promise<SearchResult> {11 const limit = Math.min(Math.max(p.limit ?? 24, 1), 500), offset = Math.max(p.offset ?? 0, 0);12 const direct = await searchDirect(p).catch(() => [] as ListingCard[]);13 if (!direct.length) return searchAggregated(p);14 // fusion : on récupère la fenêtre agrégée élargie puis on intercale les annonces directes selon le tri15 const agg = searchAggregated({ ...p, limit: Math.min(limit + direct.length, 500), offset: Math.max(0, offset - direct.length) });16 const merged = sortCards([...direct, ...agg.items], p.sort);17 const seen = new Set<string>(); const items = merged.filter((c) => (seen.has(c.uid) ? false : (seen.add(c.uid), true)));18 const start = offset < direct.length ? offset : 0;19 return { items: items.slice(start, start + limit), total: agg.total + direct.length, limit, offset };20}21export async function unifiedPoints(p: SearchParams) {22 const direct = await searchDirect({ ...p, limit: 3000 }).catch(() => [] as ListingCard[]);23 return [...direct.filter((i) => i.lat != null && i.lng != null && i.price != null).map((i) => ({ uid: i.uid, lat: i.lat!, lng: i.lng!, price: i.price!, category: i.category, propertyId: i.propertyId })), ...aggPoints(p)];24}25