SPB Git forge

spb/house-ka

Public
18commits 1branches 0releases
1.9 MBsize
maindefault branch
19 days agolast push
Python 67% TypeScript 18.2% CSS 14.4%

docs: README ultra détaillé + visite guidée en 10 captures

Simon-Pierre Boucher committed 26 days ago (Aug 29, 2026) parent 5067ae6

11 changed files +271 −30

modified README.md +271 −30
@@ -1,29 +1,221 @@
1 1 # House-Ka
2 2
3 −**www.house-ka.com** — Homes-for-sale aggregator for Canada **outside Québec**,
4 −Ontario first. A Groupe KA service, sister site of
5 −[Immo-Ka](https://www.immo-ka.com) (Québec).
3 +**[www.house-ka.com](https://www.house-ka.com)** — *Every home for sale. One place.*
6 4
7 −House-Ka continuously aggregates homes publicly listed by Canadian real-estate
8 −brokerages and teams whose sites run the **RealtyPress** WordPress plugin on
9 −the **CREA DDF** feed. Each site exposes its board's full inventory; a single
10 −generic connector (`immoka/connectors/realtypress.py`) covers them all, and
11 −cross-site duplicates are masked by DDF number (`external_id = ddf<id>`).
5 +Homes-for-sale aggregator for Canada **outside Québec**, Ontario first — a
6 +**Groupe KA** service and the English-language sister site of
7 +[Immo-Ka](https://www.immo-ka.com) (Québec). House-Ka continuously aggregates
8 +homes publicly listed by Canadian real-estate brokerages, teams and national
9 +networks, with photos, details, maps, live mortgage rates and a direct link
10 +back to each source's original listing.
11 +
12 +> House-Ka is an independent aggregator: it is not a brokerage, does not
13 +> represent buyers or sellers, and is not affiliated with the sources it
14 +> indexes. Prices and availability are those displayed by each source.
15 +
16 +## At a glance (live, 2026-08-28)
17 +
18 +| Metric | Value |
19 +|---|---|
20 +| Homes published (deduplicated) | **~258,000** |
21 +| Cities & towns | **5,991** |
22 +| Active sources | **28** CREA DDF brokerage feeds (247 offices) |
23 +| Average asking price | ~$913,000 (from $360 to $79M) |
24 +| Average data completeness | 77.6 / 100 |
25 +| Coverage | 9 provinces + 2 territories (all of Canada except Québec & Nunavut) |
26 +| Launched | 2026-08-27 |
27 +
28 +---
29 +
30 +## Guided tour
31 +
32 +Ten screenshots of the live site (in `docs/screenshots/`).
33 +
34 +### 1 — Home: search every home in one place
35 +[`https://www.house-ka.com/`](https://www.house-ka.com/)
36 +
37 +![Home page](docs/screenshots/01-accueil.jpg)
38 +
39 +The landing page states the mission — *"Every home for sale. One place."* —
40 +above the live counters (homes indexed, cities & towns, average and highest
41 +price). A scrolling ticker streams per-source volumes in real time
42 +(Century 21 Ontario, The Cody Group, Century 21 BC…). Below, the search bar
43 +("Where do you want to live?") combines city, property type and price-range
44 +filters with one-tap type chips (House, Land, Condo, Townhouse, Multi-family,
45 +Mobile home, Farm), and the result header offers sorting plus a List / Map
46 +toggle. The pine-green / cream / serif skin is deliberately distinct from
47 +Immo-Ka's cherry theme.
48 +
49 +### 2 — Property page: full listing detail
50 +[`https://www.house-ka.com/property/c21_ab%3Ac21123293118/2-amp-72-highways-rural-rocky-view-county`](https://www.house-ka.com/property/c21_ab%3Ac21123293118/2-amp-72-highways-rural-rocky-view-county)
51 +
52 +![Property page](docs/screenshots/02-property-c21_ab-3Ac21123293118-2-amp-72-highways-rural-rocky.jpg)
53 +
54 +A listing detail page (`/property/{uid}/{slug}`) — here a $2,900,000 land
55 +parcel in Rural Rocky View County, Alberta from the Century 21 Canada —
56 +Alberta feed. Photo gallery on top, then asking price with the canonical type
57 +badge, address with province, a favorites heart (KA ID accounts), breadcrumb
58 +navigation, and a **Location** card rendered by Ka Maps with the price marker
59 +and the listing's building/lot highlighted. The DOM order follows the Groupe
60 +KA detail-page standard (gallery → price → description → details → analyses →
61 +map), identical on mobile and desktop.
62 +
63 +### 3 — Live mortgage rates
64 +[`https://www.house-ka.com/rates`](https://www.house-ka.com/rates)
65 +
66 +![Mortgage rates](docs/screenshots/03-rates.jpg)
67 +
68 +The `/rates` page publishes the rates **actually posted** by the big Canadian
69 +institutions (banks, virtual lenders, monolines), collected continuously by
70 +the shared Groupe KA mortgage engine. The market overview shows the best rate
71 +per term (fixed 1/3/4/5/10 years, 5-year variable) with the median and 30-day
72 +trend, plus every institution's prime rate. The comparison table lists each
73 +product with its **kind** (posted or special offer), **freshness** and a link
74 +to the **official source** — never an invented rate, never a stale one
75 +without a warning.
76 +
77 +### 4 — Platform statistics & data quality
78 +[`https://www.house-ka.com/stats`](https://www.house-ka.com/stats)
79 +
80 +![Platform statistics](docs/screenshots/04-stats.jpg)
81 +
82 +The `/stats` dashboard exposes the platform's own numbers live: homes for
83 +sale, cities, average price, source count — and, unusually for a listings
84 +site, its full **data-quality layer**: active vs published listings,
85 +quarantine size, average completeness score, and a per-source table with
86 +listing counts, completeness and anomaly flags. Every listing gets a
87 +completeness score (photos, description, specs, coordinates); listings
88 +without a plausible price or a known city are quarantined until the next
89 +enrichment pass completes them.
90 +
91 +### 5 — Sources by brokerage
92 +[`https://www.house-ka.com/agencies`](https://www.house-ka.com/agencies)
93 +
94 +![Brokerages](docs/screenshots/05-agencies.jpg)
95 +
96 +The `/agencies` registry lists every covered brokerage and team — 28 banners,
97 +247 offices — with expandable per-banner listing counts (Century 21 Canada by
98 +province, The Cody Group, Revel Realty, Grapevine…). Each source publishes
99 +its board's full inventory through the CREA DDF feed; the same property
100 +published on several sites is only counted once (deduplication by DDF
101 +number). Clicking a source filters the search to its homes.
102 +
103 +### 6 — Contact
104 +[`https://www.house-ka.com/contact`](https://www.house-ka.com/contact)
105 +
106 +![Contact](docs/screenshots/06-contact.jpg)
107 +
108 +The contact page, with the House-Ka identity and the Groupe KA footer linking
109 +to the sister services.
110 +
111 +### 7 — Map view: the whole country on one map
112 +[`https://www.house-ka.com/?view=map`](https://www.house-ka.com/?view=map)
113 +
114 +![Map view](docs/screenshots/07-accueil.jpg)
115 +
116 +The split list/map view powered by **Ka Maps** (`@groupe-ka/ka-maps`, the
117 +shared Groupe KA Mapbox framework). Clusters show the listing count with the
118 +approximate median price underneath; "search this area" re-queries the
119 +viewport, and the list panel stays in sync with the markers by construction
120 +(single `/api/listings` search backend). 2D/3D toggle, drawing tool and
121 +geolocation included.
122 +
123 +### 8 — Account: KA ID single sign-on
124 +[`https://www.house-ka.com/account`](https://www.house-ka.com/account)
125 +
126 +![Account](docs/screenshots/08-account.jpg)
127 +
128 +The `/account` page plugs into **KA ID**, the central Groupe KA identity
129 +(groupe-ka.com): one member identifier valid across the whole ecosystem.
130 +Signed-in users get cross-site favorites ("My Ka universe"). The footer
131 +presents the ecosystem: Groupe-Ka portal, Immo-Ka (homes for sale in Québec),
132 +Lou-Ka (rentals in Québec), Vrai-Prix (Québec market-value estimates).
133 +
134 +### 9 — Terms of use
135 +[`https://www.house-ka.com/terms`](https://www.house-ka.com/terms)
136 +
137 +![Terms](docs/screenshots/09-terms.jpg)
138 +
139 +Terms of use — including the independent-aggregator disclaimer and the rules
140 +for source attribution and linking back to original listings.
141 +
142 +### 10 — Privacy policy
143 +[`https://www.house-ka.com/privacy`](https://www.house-ka.com/privacy)
144 +
145 +![Privacy](docs/screenshots/10-privacy.jpg)
146 +
147 +Privacy policy: what is collected (KA ID account data, favorites), what is
148 +not, and how the analytics distinguish human traffic.
149 +
150 +---
151 +
152 +## Features
153 +
154 +- **Nationwide search** — by city/town (5,991 of them), property type, price
155 + range and free-text query; quick type chips; newest-first and price
156 + sorting; list or map view.
157 +- **Programmatic SEO pages** — `/for-sale/{city}` and
158 + `/for-sale/{city}/{type}` city pages plus `/type/{type}` pages, all
159 + server-rendered with meta, JSON-LD and sitemaps (in English, `en_CA`).
160 +- **Listing pages** — gallery, price, canonical type, specs, description,
161 + nearby commerce banners adapted to each province, Ka Maps location card,
162 + link to the original listing.
163 +- **Live mortgage rates** — national Canadian rates with kind, freshness and
164 + official source per product (shared `immoka/mortgage/` engine, see
165 + `docs/mortgage-engine.md`).
166 +- **Transparent statistics** — public `/stats` dashboard including the
167 + quality layer (quarantine, completeness, anomaly flags per source).
168 +- **KA ID accounts & favorites** — Groupe KA single sign-on, cross-site
169 + favorites hub.
170 +- **Data quality pipeline** — completeness scoring, quarantine, image audit,
171 + coordinate guard covering all of Canada, cross-site dedup.
172 +
173 +## Data & sources
174 +
175 +All 28 active sources are Canadian brokerage / team / network sites whose
176 +inventories come from the **CREA DDF** feed:
177 +
178 +- **RealtyPress connector** (`immoka/connectors/realtypress.py`) — one
179 + generic connector covers every brokerage or team site running the
180 + RealtyPress WordPress plugin (Revel Realty, The Cody Group, Grapevine,
181 + Sutton Ottawa, Hanlon Realty…). Each site exposes its board's full
182 + inventory; cross-site duplicates are masked by DDF number
183 + (`external_id = ddf<id>`, dedup by `MIN(uid)`).
184 +- **Century 21 Canada connector** (`immoka/connectors/c21_canada.py`) — one
185 + provincial source per region: BC, AB, SK, MB, ON, NB, NS, PE, NL, YT, NT.
186 + (Saskatchewan has no polygon API and is searched via ~30 cities; the
187 + Alberta watcher uses adaptive sleep for cycles longer than 24 h.)
188 +
189 +DDF list cards carry no property type: most listings get their type when
190 +their detail page is fetched (`IMMOKA_RP_DETAIL_LIMIT` per source per sync).
191 +Sources are declared in `data/sources.json` and the site census lives in
192 +`data/canada_agencies.json`; the checked-in `sources.json` documents the
193 +initial registry.
194 +
195 +### Canonical property types (English)
196 +
197 +`House, Condo, Townhouse, Semi-detached, Duplex, Triplex, Multi-family,
198 +Cottage, Mobile home, Land, Farm, Commercial, Parking` —
199 +see `immoka/normalize.py`.
12 200
13 201 ## Architecture
14 202
15 −Forked from Immo-Ka on 2026-08-27 (the Ontario expansion paused there moved
16 −here). The Python package keeps its historical name `immoka`.
203 +Forked from **Immo-Ka** on 2026-08-27 (the Ontario expansion paused there
204 +moved here — see the immo-ka repo's `docs/ONTARIO-PAUSE.md`). The Python
205 +package keeps its historical name `immoka`.
17 206
18 −- **Backend** — FastAPI + SQLite (`data/immoka.db`), same pipeline as Immo-Ka:
19 − connectors → `ingest` → dedup → `quality` (relaxed publication rule: price +
20 − city; type/description enrich over time via detail passes) → API.
207 +- **Backend** — FastAPI + SQLite (`data/immoka.db`), same pipeline as
208 + Immo-Ka: connectors → `ingest` → dedup → `quality` (relaxed publication
209 + rule: price + city; type/description enrich over time via detail passes) →
210 + API. Sync loop runs every 240 minutes under PM2.
21 211 - **Frontend** — React/Vite, **English**, pine/cream/serif skin (deliberately
22 − different from Immo-Ka's cherry). Routes: `/`, `/property/{uid}[/{slug}]`,
23 − `/for-sale/{city}[/{type}]`, `/type/{type}`, `/rates`, `/agencies`, `/stats`.
24 − Map = Ka Maps (`@groupe-ka/ka-maps`, expected at `../../ka-maps`).
25 −- **SEO** — `immoka/seo.py` renders server-side HTML (meta, JSON-LD, sitemaps)
26 − in English.
212 + different from Immo-Ka's cherry). SPA routes: `/`, `/property/{uid}[/{slug}]`,
213 + `/rates`, `/agencies`, `/stats`, `/account`, `/contact`, `/terms`,
214 + `/privacy`; SEO routes `/for-sale/{city}[/{type}]` and `/type/{type}` are
215 + resolved server-side. Map = Ka Maps (`@groupe-ka/ka-maps`, expected at
216 + `../../ka-maps`).
217 +- **SEO** — `immoka/seo.py` renders server-side HTML (meta, JSON-LD,
218 + sitemaps, `robots.txt`) in English.
27 219 - **Mortgage engine** — shared with Immo-Ka (`immoka/mortgage/`), national
28 220 Canadian rates. See `docs/mortgage-engine.md`.
29 221 - **Removed vs Immo-Ka** — everything Québec-only: Hydro-Québec estimates,
@@ -31,33 +223,70 @@ here). The Python package keeps its historical name `immoka`.
31 223 Vrai-Prix, movers/inspectors directories, PDF listing sheets, all QC
32 224 connectors.
33 225
34 −## Canonical property types (English)
226 +### Repository layout
35 227
36 −`House, Condo, Townhouse, Semi-detached, Duplex, Triplex, Multi-family,
37 −Cottage, Mobile home, Land, Farm, Commercial, Parking` —
38 −see `immoka/normalize.py`. DDF list cards carry no type: most listings get
39 −their type when their detail page is fetched (`IMMOKA_RP_DETAIL_LIMIT` per
40 −source per sync).
228 +```
229 +run.py CLI entry point (sync / watch / serve / list / geocode / mortgage-sync)
230 +immoka/ Python package (historical name kept from the Immo-Ka fork)
231 + web.py FastAPI app: API + SEO HTML + SPA fallback
232 + ingest.py, quality.py, normalize.py, schema.py, db.py
233 + seo.py English server-side SEO (meta, JSON-LD, sitemaps)
234 + geocode.py, imgaudit.py, stats.py, commerces.py, poi.py
235 + auth.py, kaid.py, favorites.py, hubfav.py, hubprofile.py (KA ID SSO + favorites)
236 + mortgage/ shared Groupe KA mortgage-rate engine (+ /api/mortgage)
237 + connectors/ realtypress.py, c21_canada.py, base.py, jsonld.py, _detailutil.py, _resilient.py
238 +frontend/ React/Vite SPA (src/pages: Home, Listing, Rates, Stats, Agencies, Account, Contact, Legal)
239 +scripts/ scouting & maintenance (scout_canada_rp*.py, gen_connector_docs.py, …)
240 +docs/ mortgage-engine.md, ontario-agencies.md, screenshots/
241 +data/ SQLite DB + live registries (not committed)
242 +```
243 +
244 +## API
245 +
246 +| Route | Description |
247 +|---|---|
248 +| `GET /api/listings` | search (city, type, price, text, bbox/polygon, sort, pagination) |
249 +| `GET /api/listings/{uid}` | full listing detail |
250 +| `GET /api/listings.geojson` | map markers/clusters feed |
251 +| `GET /api/facets` | cities, property types, sources facets |
252 +| `GET /api/agencies` | brokerage/office registry with counts |
253 +| `GET /api/stats` | live platform + quality statistics |
254 +| `GET /api/stats/catalog`, `/dashboard`, `/report` | stats module (kacharts/kapdf, custom reports via `POST /api/stats/report/custom`) |
255 +| `GET /api/mortgage` | live mortgage rates |
256 +| `GET /api/commerces` | nearby commerce banners per province |
257 +| `/api/auth`, `/api/favorites` | KA ID session + favorites |
258 +| `GET /api/sources`, `POST /api/sync` | connector registry & manual sync |
259 +| `GET /api/seo/resolve`, `/sitemap.xml`, `/sitemaps/{name}`, `/robots.txt` | SEO plumbing |
41 260
42 261 ## Run
43 262
44 263 ```bash
45 264 python run.py sync [source ...] # sync listings
46 −python run.py watch [minutes] # sync loop (default 60 min)
265 +python run.py watch [minutes] # sync loop (default 60 min; prod uses 240)
47 266 python run.py serve [port] # API + frontend (default 8098)
48 267 python run.py list # registered connectors
49 268 python run.py geocode [n] # geocode listings missing coordinates
50 269 python run.py mortgage-sync # collect mortgage rates
51 270 ```
52 271
53 −`.env`: `IMMOKA_BASE_URL=https://www.house-ka.com`,
54 −`IMMOKA_RP_DETAIL_LIMIT=<n>` (detail pages fetched per source per sync).
272 +`.env` (see `.env.example`, never committed): `IMMOKA_BASE_URL=https://www.house-ka.com`,
273 +`IMMOKA_RP_DETAIL_LIMIT=<n>` (detail pages fetched per source per sync),
274 +plus optional scraping/SSO/mortgage-engine settings.
55 275
56 276 ## Deployment
57 277
58 −M4M64b, `~/apps/house-ka`, PM2 (`house-ka-web` :8098, `house-ka-sync`,
59 −`house-ka-ngrok` → www.house-ka.com). Remote-first: the repo on the node is
60 −the source of truth, `origin` = spbgit (`gitsrv:house-ka.git`).
278 +Node **M4M64b**, `~/apps/house-ka`, PM2:
279 +
280 +| Process | Role |
281 +|---|---|
282 +| `house-ka-web` | `run.py serve` on port **8098** |
283 +| `house-ka-sync` | `run.py watch 240` (sync loop every 4 h) |
284 +| `house-ka-ngrok` | tunnel → **www.house-ka.com** |
285 +
286 +Remote-first: the repo **on the node** is the source of truth (never the
287 +laptop copies); `origin` = spbgit, the personal git server
288 +(`gitsrv:srv/git/house-ka.git`, bare repos on M3U96a). Edit over SSH, build,
289 +`pm2 restart`, then commit & push from the node (agent forwarding).
61 290
62 291 ## Adding sources (rest of Canada)
63 292
@@ -65,3 +294,15 @@ RealtyPress sites exist across Canada. Census & instructions:
65 294 `docs/ontario-agencies.md` (method transposes to any province). Add the site
66 295 to `data/canada_agencies.json` + an entry in `data/sources.json`, then
67 296 `python run.py sync <id>`. The coordinate guard covers all of Canada.
297 +
298 +## Groupe KA ecosystem
299 +
300 +House-Ka is one of the Groupe KA platforms ([groupe-ka.com](https://www.groupe-ka.com)):
301 +Immo-Ka (homes for sale, Québec), Lou-Ka (rentals, Québec), Rent-Ka (rentals,
302 +Canada outside Québec), Vrai-Prix (market-value estimates), Auto-Ka, Food-Ka,
303 +Resto-Ka, Sorti-Ka, Job-Ka, Trouve-Ka, Crea-Ka, Fabri-Ka — all sharing KA ID,
304 +the ka-ui design system, Ka Maps and the stats/PDF modules.
305 +
306 +## Contact
307 +
308 +Simon-Pierre Boucher — contact@spboucher.ai — © 2026 Groupe-Ka
added docs/screenshots/01-accueil.jpg +0 −0

Binary file not shown.

added docs/screenshots/02-property-c21_ab-3Ac21123293118-2-amp-72-highways-rural-rocky.jpg +0 −0

Binary file not shown.

added docs/screenshots/03-rates.jpg +0 −0

Binary file not shown.

added docs/screenshots/04-stats.jpg +0 −0

Binary file not shown.

added docs/screenshots/05-agencies.jpg +0 −0

Binary file not shown.

added docs/screenshots/06-contact.jpg +0 −0

Binary file not shown.

added docs/screenshots/07-accueil.jpg +0 −0

Binary file not shown.

added docs/screenshots/08-account.jpg +0 −0

Binary file not shown.

added docs/screenshots/09-terms.jpg +0 −0

Binary file not shown.

added docs/screenshots/10-privacy.jpg +0 −0

Binary file not shown.