SPB Git forge

spb/immo-ka

Public

Immo-Ka — agrégateur des propriétés à vendre au Québec (73 connecteurs, ~40 000 annonces, React+FastAPI)

112commits 1branches 0releases
125.4 MBsize
maindefault branch
13 days agolast push
Python 47.5% HTML 27.9% TypeScript 15.5% CSS 7.2% JavaScript 2%
3.0 KB · 104 lines typescript
Raw Blame History
1// -----------------------------------------------------------------------------2// Author: Simon-Pierre Boucher3// Contact: contact@spboucher.ai4// Project: Groupe Ka / Ka Maps (Immo-Ka integration)5// kamaps/adapter.ts : adaptateur Immo-Ka → MapProperty. Le drapeau6// « highlight » marque les prix sous l'estimation Vrai-Prix (bonne affaire),7// même règle que l'ancienne carte : price ≤ vp×0,95 et ≥ vp×0,5.8// -----------------------------------------------------------------------------9import type {10  BoundsQuery,11  BoundsQueryResult,12  KaDataAdapter,13  MapProperty,14} from "@groupe-ka/ka-maps";15import { bboxToString } from "@groupe-ka/ka-maps";16import type { ListingFilters } from "../api";1718interface ImmoKaFeatureProps {19  uid: string;20  title: string | null;21  address: string | null;22  price: number | null;23  price_label: string | null;24  property_type: string | null;25  bedrooms: number | null;26  bathrooms: number | null;27  source: string;28  city: string | null;29  sector: string | null;30  image: string | null;31  vp: number | null;32}3334interface ImmoKaFC {35  type: "FeatureCollection";36  features: {37    geometry: { coordinates: [number, number] };38    properties: ImmoKaFeatureProps;39  }[];40  totalGeocoded?: number;41  totalMatching?: number;42}4344function toMapProperty(45  coords: [number, number],46  p: ImmoKaFeatureProps,47): MapProperty {48  const deal =49    p.price != null && p.vp != null && p.price <= p.vp * 0.95 && p.price >= p.vp * 0.5;50  return {51    id: p.uid,52    appSource: "immo-ka",53    longitude: coords[0],54    latitude: coords[1],55    kind: "listing",56    listingType: "sale",57    price: p.price ?? undefined,58    estimatedValue: p.vp ?? undefined,59    propertyType: p.property_type ?? undefined,60    bedrooms: p.bedrooms ?? undefined,61    bathrooms: p.bathrooms ?? undefined,62    address: p.address ?? p.title ?? undefined,63    city: p.city ?? undefined,64    region: p.sector ?? undefined,65    thumbnailUrl: p.image ?? undefined,66    originalUrl: `/propriete/${encodeURIComponent(p.uid)}`,67    highlight: deal,68    extra: {69      title: p.title,70      priceLabel: p.price_label,71      source: p.source,72      vp: p.vp,73    },74  };75}7677/** Adaptateur viewport→données pour la carte Immo-Ka. */78export const immoKaMapAdapter: KaDataAdapter = {79  id: "immo-ka-listings",80  appSource: "immo-ka",81  async fetchInBounds(query: BoundsQuery): Promise<BoundsQueryResult> {82    const params = new URLSearchParams();83    const filters = (query.filters ?? {}) as Partial<ListingFilters>;84    for (const [k, v] of Object.entries(filters)) {85      if (v && k !== "sort") params.set(k, String(v));86    }87    params.set("bbox", bboxToString(query.bbox));88    params.set("limit", "3000");8990    const res = await fetch(`/api/listings.geojson?${params}`, {91      signal: query.signal,92    });93    if (!res.ok) throw new Error(`Carte : API ${res.status}`);94    const data = (await res.json()) as ImmoKaFC;9596    return {97      properties: data.features.map((f) =>98        toMapProperty(f.geometry.coordinates, f.properties),99      ),100      totalCount: data.totalMatching,101    };102  },103};104