Python 49.6%
TypeScript 25.5%
CSS 24.1%
1> ⚠️ **URL live hors fonction pour le moment.** L'application a été retirée du cluster MacLustr le 2026-09-04 (processus arrêtés, copie du nœud supprimée). Ce dépôt spbgit est désormais la seule source de vérité du projet. Ancienne URL : https://www.home-ka.com23<h1 align="center">Home·Ka</h1>45<p align="center"><b>US real-estate aggregator — every home for sale, from direct feeds first.</b><br>6<a href="https://www.home-ka.com">www.home-ka.com</a> · Groupe KA · US counterpart of <a href="https://www.immo-ka.com">Immo·Ka</a> (Canada)</p>78**Home-Ka** reuses the Immo-Ka architecture end to end — connectors, normalization, ingestion, property matching, deduplication, quality gate, search API, Ka Maps frontend — adapted to the US market: **RESO Data Dictionary** as the schema reference, USD/sq ft/USPS states, US Census geocoder, and a **brokerage partnership pipeline** designed to convert sources into direct feeds instead of crawling.910## Pipeline (same philosophy as Immo-Ka)1112```13SOURCE → connector → raw ingestion → normalization → property matching14 → deduplication → canonical listing → search index → Home-Ka15```1617- **PROPERTY ≠ LISTING** — a `Listing` is one publication by one source; a `Property` (`properties` table, keyed by APN or normalized address) is the physical asset and keeps existing after the listing goes off-market. Every listing is matched on ingest (`homeka/propertymatch.py`).18- **Change detection** — content hash per listing, price history (`price_log`), grace period (2 syncs) before deactivation, drift detection (volume/price collapse suspends removals).19- **Dedup** — precomputed (`dup_hidden`/`dup_of`): same MLS number across sources, or same property at ±1% price; most authoritative source wins (`sources.authority`: direct feed < partner API < site < classifieds).20- **Quality gate** — completeness score, quarantine below threshold (`published=0`).21- **Geocoding** — US Census batch geocoder (free, 5k/req) + budgeted Nominatim fallback, persistent cache.2223## Connector families (`homeka/connectors/`)2425| Family | Module | Use |26|---|---|---|27| `reso` | `reso/webapi.py` | **RESO Web API (OData)** — MLS Grid, Trestle, Bridge, Spark… the preferred feed |28| `rets` | `rets/client.py` | legacy RETS (login + DMQL2, COMPACT-DECODED) |29| `xml` | `xml/feed.py` | XML exports / syndication feeds |30| `json` | `json/feed.py` | JSON partner APIs, wp-json, internal search APIs |31| `jsonld` | `json/jsonld_site.py` | schema.org JSON-LD site crawler (bootstrap only) |32| `csv` | `csv/feed.py` | CSV exports |33| `sftp` | `sftp/drop.py` | SFTP drops (csv/xml), newest file by mtime |34| `arcgis` | `public_data/arcgis.py` | county assessor/GIS parcels → feeds **properties**, not listings |35| custom | `custom_broker/*.py` | one class per site when a family can't express it |3637A new source of a known family = **one row in the `sources` table** (`config` JSON: URL, field mapping, `$ENV:NAME` credentials), zero code. Custom connectors auto-register via `source_id`, exactly like Immo-Ka. Anti-bot policy: direct requests first; auto-escalation chain (Oxylabs → Scrapfly ASP → Bright Data, `connectors/_resilient.py`) only when blocked.3839## Brokerage pipeline (`/admin/brokerages`)4041```42discover brokerage → inspect website → detect IDX/feed/provider43→ find public contacts → classify connector → score → admin44```4546- Seed: **630 real US brokerages** (`data/brokerages_seed.json`, `python run.py seed`).47- `homeka/discovery.py` inspects each website (direct GET): IDX platform fingerprints (kvCORE, iHomefinder, IDX Broker, Sierra, REW, Delta Media, Ylopo…), RESO/RETS hints, MLS affiliations, contact/partnership emails; then scores `feed_probability_score` and `priority_score` (size × feed probability × coverage).48- Partnership statuses: prospect → to-contact → contacted → in-discussion → feed-received → **live** (linked to a `sources` row).4950## Run5152```bash53python run.py serve 8099 # API + frontend54python run.py sync [source ...] # one-shot ingestion55python run.py watch 60 # sync loop + geocode + img audit + discovery56python run.py seed # load brokerage seed57python run.py discover 25 # inspect next prospects58python run.py list | geocode | quality | dedup | rescore59```6061Admin: `/admin` (overview), `/admin/sources`, `/admin/connectors`, `/admin/brokerages` — optional `HOMEKA_ADMIN_TOKEN` (.env) required as `X-Admin-Token`.6263## Deployment6465- Node **M4M36** (`~/apps/home-ka`), port **8099**, PM2 `home-ka-web` + `home-ka-sync` + `home-ka-ngrok` (`--url=www.home-ka.com`).66- Frontend: Vite build (`frontend/`, ka-maps vendored in `vendor/ka-maps`).67- Git: `origin` = spbgit (`gitsrv:srv/git/home-ka.git`).6869## Adding a RESO feed (example)7071```python72from homeka import db73con = db.connect()74db.upsert_source(con, "mlsgrid_actris", "MLS Grid — ACTRIS", "reso", config={75 "base_url": "https://api.mlsgrid.com/v2",76 "token": "$ENV:MLSGRID_TOKEN",77 "filter": "StandardStatus eq 'Active'",78 "expand": "Media", "originating_system": "ACTRIS",79}, authority=0, states=["TX"])80```81