// ----------------------------------------------------------------------------- // Author: Simon-Pierre Boucher // Contact: contact@spboucher.ai // Project: Groupe Ka / Ka Maps (Immo-Ka integration) // kamaps/adapter.ts : adaptateur Immo-Ka → MapProperty. Le drapeau // « highlight » marque les prix sous l'estimation Vrai-Prix (bonne affaire), // même règle que l'ancienne carte : price ≤ vp×0,95 et ≥ vp×0,5. // ----------------------------------------------------------------------------- import type { BoundsQuery, BoundsQueryResult, KaDataAdapter, MapProperty, } from "@groupe-ka/ka-maps"; import { bboxToString } from "@groupe-ka/ka-maps"; import type { ListingFilters } from "../api"; interface ImmoKaFeatureProps { uid: string; title: string | null; address: string | null; price: number | null; price_label: string | null; property_type: string | null; bedrooms: number | null; bathrooms: number | null; source: string; city: string | null; sector: string | null; image: string | null; vp: number | null; } interface ImmoKaFC { type: "FeatureCollection"; features: { geometry: { coordinates: [number, number] }; properties: ImmoKaFeatureProps; }[]; totalGeocoded?: number; totalMatching?: number; } function toMapProperty( coords: [number, number], p: ImmoKaFeatureProps, ): MapProperty { const deal = p.price != null && p.vp != null && p.price <= p.vp * 0.95 && p.price >= p.vp * 0.5; return { id: p.uid, appSource: "immo-ka", longitude: coords[0], latitude: coords[1], kind: "listing", listingType: "sale", price: p.price ?? undefined, estimatedValue: p.vp ?? undefined, propertyType: p.property_type ?? undefined, bedrooms: p.bedrooms ?? undefined, bathrooms: p.bathrooms ?? undefined, address: p.address ?? p.title ?? undefined, city: p.city ?? undefined, region: p.sector ?? undefined, thumbnailUrl: p.image ?? undefined, originalUrl: `/propriete/${encodeURIComponent(p.uid)}`, highlight: deal, extra: { title: p.title, priceLabel: p.price_label, source: p.source, vp: p.vp, }, }; } /** Adaptateur viewport→données pour la carte Immo-Ka. */ export const immoKaMapAdapter: KaDataAdapter = { id: "immo-ka-listings", appSource: "immo-ka", async fetchInBounds(query: BoundsQuery): Promise { const params = new URLSearchParams(); const filters = (query.filters ?? {}) as Partial; for (const [k, v] of Object.entries(filters)) { if (v && k !== "sort") params.set(k, String(v)); } params.set("bbox", bboxToString(query.bbox)); params.set("limit", "3000"); const res = await fetch(`/api/listings.geojson?${params}`, { signal: query.signal, }); if (!res.ok) throw new Error(`Carte : API ${res.status}`); const data = (await res.json()) as ImmoKaFC; return { properties: data.features.map((f) => toMapProperty(f.geometry.coordinates, f.properties), ), totalCount: data.totalMatching, }; }, };