# Immo·Ka ### Toutes les propriétés à vendre du Québec. Un seul endroit. **[www.immo-ka.com](https://www.immo-ka.com)** ![Python](https://img.shields.io/badge/Python-3.14-141814?style=for-the-badge&logo=python&logoColor=c7f230) ![FastAPI](https://img.shields.io/badge/FastAPI-API-141814?style=for-the-badge&logo=fastapi&logoColor=c7f230) ![React](https://img.shields.io/badge/React_18-Vite_+_TS-141814?style=for-the-badge&logo=react&logoColor=c7f230) ![MapLibre](https://img.shields.io/badge/MapLibre-carte-141814?style=for-the-badge&logo=maplibre&logoColor=c7f230) ![SQLite](https://img.shields.io/badge/SQLite-WAL-141814?style=for-the-badge&logo=sqlite&logoColor=c7f230) ![Propriétés](https://img.shields.io/badge/propri%C3%A9t%C3%A9s_agr%C3%A9g%C3%A9es-40_000%2B-1c5c41?style=flat-square) ![Connecteurs](https://img.shields.io/badge/connecteurs-73-1c5c41?style=flat-square) ![Agences](https://img.shields.io/badge/agences_actives-21-1c5c41?style=flat-square) ![Couverture](https://img.shields.io/badge/couverture-tout_le_Qu%C3%A9bec-1c5c41?style=flat-square) ![MàJ](https://img.shields.io/badge/mise_%C3%A0_jour-automatique-1c5c41?style=flat-square) *Agrégateur indépendant des maisons, condos et terrains à vendre au Québec — un connecteur dédié par agence de courtage, chaque propriété normalisée vers un schéma unique, avec galerie photo, caractéristiques complètes et lien direct vers l'annonce originale de l'agence. Toujours à jour, automatiquement.*
--- ## Aperçu | Accueil — liste, filtres & carte | Fiche propriété — galerie & specs | |---|---| | ![Accueil Immo-Ka](docs/screenshots/home.png) | ![Fiche propriété](docs/screenshots/listing.png) | ## Pourquoi Immo-Ka ? Chercher une propriété à vendre au Québec, c'est jongler entre les sites de RE/MAX, Royal LePage, Sutton, Via Capitale, Century 21 et des dizaines d'autres bannières — chacun avec sa navigation, ses filtres, son format. **Immo-Ka retourne le problème** : un connecteur par agence visite chaque source, normalise chaque propriété vers un schéma unique, et détecte les changements en continu. > Les sites d'agences n'offrent pas de webhooks. Immo-Ka reproduit l'équivalent : > **synchronisation périodique + hash de contenu** → ajouts, changements de prix et > retraits (propriété vendue) détectés automatiquement. C'est le pendant « à vendre » de [Lou-Ka](https://www.lou-ka.com) (location) — même architecture, schéma adapté à la vente. ## Couverture (métriques en direct) | Agence | Propriétés | Méthode technique | |---|---:|---| | RE/MAX Québec | ~25 300 | Meilisearch public + sharding FSA postal + page détail | | Via Capitale | ~5 250 | portail central (Firecrawl stealth, pagination `criteresJson`) | | Sutton | ~4 500 | sitemap `sitemap_inscription.cfm` → n° Centris | | Proprio Direct | ~2 440 | API interne JSON | | Engel & Völkers | ~1 240 | property-sitemap → JSON-LD | | Royal LePage | ~1 000+ | recherche par ville filtrée QC + sharding + dédup MLS | | Century 21 | ~1 600 | sous-agences source.immo (« All Quebec ») | | Keller Williams (Urbain + Distinction) | ~510 | HTML rendu serveur + sitemap | | Barnes Québec | ~340 | Algolia + page détail | | Profusion (Christie's) | ~360 | WordPress + JSON-LD | | M Immobilier · Vendirect · Sotheby's · L'Expert PM | ~180 | Centris / source.immo / JSON-LD | | Sous-agences RE/MAX / Via Capitale / Century 21 | *backup* | 60+ connecteurs `*_ag_*`, dédup par n° Centris | **≈ 40 000 propriétés dédupliquées**, mises à jour automatiquement. Les sous-agences servent de plan B : si le flux central d'une bannière tombe, elles prennent le relais sans double-comptage (déduplication par numéro Centris). ## Architecture ```mermaid flowchart LR subgraph Sources["Agences de courtage du Québec"] S1["RE/MAX · Royal LePage · Sutton
Via Capitale · Century 21 · Proprio Direct
Engel & Völkers · Barnes · Profusion
… 73 connecteurs"] end subgraph ImmoKa["Immo-Ka"] C["Connecteurs
1 adaptateur / agence"] --> N["Normalisation
schéma PropertyListing"] N --> D[("SQLite WAL
hash + diff + dédup Centris")] D --> A["API FastAPI
/api/listings · /api/facets · geojson"] A --> F["React 18 + Vite + MapLibre
liste · carte · fiche détaillée"] end W["⏱ Watcher (PM2)"] -.-> C S1 --> C F --> U["🔑 Acheteur"] ``` | Couche | Rôle | Fichiers | |---|---|---| | **Connecteurs** | 1 module par agence : API JSON interne (Meilisearch, Algolia, source.immo, wp-json), JSON-LD, sitemap, ou Firecrawl pour les sites SPA/anti-bot | `immoka/connectors/*.py` | | **Schéma** | `PropertyListing` : adresse, secteur, ville, région, type, prix, chambres/SdB, superficie, terrain, année, MLS, courtier, pièces (dimensions), **toutes les photos** | `immoka/schema.py` | | **Diff engine** | upsert par hash de contenu, délai de grâce, détection de dérive, historique de prix, **déduplication inter-agences par n° Centris** | `immoka/db.py`, `immoka/web.py` | | **API** | filtres ville/secteur/région/type/agence/prix/chambres, facettes, stats, GeoJSON | `immoka/web.py` | | **Frontend** | React 18 + Vite + TS + react-router + MapLibre : accueil (liste/carte), fiche par propriété (galerie + lightbox, caractéristiques, pièces, historique de prix, courtier, mini-carte), Stats, Agences | `frontend/` | ## Démarrage rapide ```bash python3 -m venv .venv && .venv/bin/pip install -r requirements.txt # frontend cd frontend && npm install && npm run build && cd .. # (optionnel) sites JavaScript / anti-bot echo "FIRECRAWL_API_KEY=fc-votre-cle" > .env .venv/bin/python run.py list # connecteurs enregistrés .venv/bin/python run.py sync # toutes les agences (ou: sync remax_quebec sutton) .venv/bin/python run.py serve 8090 # API + frontend → http://localhost:8090 .venv/bin/python run.py watch 180 # synchronisation en boucle ``` ## Ajouter une agence 1. Créer `immoka/connectors/.py` : sous-classe de `BaseConnector`, définir `source_id`, implémenter `fetch() -> list[PropertyListing]`. Le registre est **auto-découvrant** — aucun fichier partagé à modifier. 2. Ajouter l'entrée dans `data/sources.json`. 3. Tester : `.venv/bin/python run.py sync `. Pour une bannière à sous-agences (RE/MAX, Via Capitale, Century 21), un module génère un connecteur par sous-agence depuis un registre JSON — nommer les `source_id` en `_ag_` active automatiquement la déduplication. ## Déploiement Déployé sur le cluster MacLustr (nœud M4M64a) via PM2 : `immo-ka-web` (API + frontend), `immo-ka-sync` (watcher horaire), `immo-ka-ngrok` (tunnel `www.immo-ka.com`). Base SQLite en mode WAL pour les accès concurrents. --- ## Auteur **Simon-Pierre Boucher** 📧 [contact@spboucher.ai](mailto:contact@spboucher.ai) *Agrégateur indépendant — les annonces proviennent des sites publics des agences de courtage et sont rafraîchies automatiquement ; chaque fiche renvoie vers l'annonce originale de l'agence.*