SPB Git

spb/rent-ka

Public

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

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Simon-Pierre Boucher committed (Aug 29, 2026) parent 5441abe Browse files

11 changed files +299 −25

modified README.md +299 −25
@@ -1,15 +1,179 @@
1 <!-- Author: Simon-Pierre Boucher — contact@spboucher.ai --> 1 <!-- Author: Simon-Pierre Boucher — contact@spboucher.ai -->
2 2
3+<p align="center">
4+ <img src="frontend/public/og.png" alt="Rent-Ka — Apartments and homes for rent across Canada" width="720">
5+</p>
6+
3 # Rent-Ka 7 # Rent-Ka
4 8
5−**www.rent-ka.com** — Apartments and homes for rent across **Canada outside 9+**[www.rent-ka.com](https://www.rent-ka.com)** — Apartments and homes for rent
6−Québec** (Ontario first, national expansion in progress). A Groupe KA 10+across **Canada outside Québec** (Ontario first, national expansion live). A
7−service, sister site of [Lou-Ka](https://www.lou-ka.com) (Québec rentals) 11+**Groupe KA** service, sister site of [Lou-Ka](https://www.lou-ka.com) (Québec
8−and [House-Ka](https://www.house-ka.com) (Canadian homes for sale). 12+rentals) and [House-Ka](https://www.house-ka.com) (Canadian homes for sale).
13+
14+Rent-Ka continuously aggregates rental listings published by Canadian property
15+managers, REITs, real-estate brokers and national portals: every listing keeps
16+its photos, price, availability and a **direct link to the original ad**.
17+Groupe KA is a content aggregator — we sell nothing, rent nothing and are not
18+a party to any transaction.
19+
20+**Live snapshot (2026-08-28)** · ~76,000 rentals indexed · **767 registered
21+connectors** · listings in 9 provinces + 2 territories (all of Canada except
22+Québec) · average rent **$2,180/month** · ~1,800 cities covered · top markets:
23+Toronto, Calgary, Edmonton, Ottawa, Hamilton, Vancouver, Mississauga, London,
24+Winnipeg, Kitchener.
25+
26+---
27+
28+## Table of contents
29+
30+1. [Guided tour (screenshots)](#guided-tour)
31+2. [Features](#features)
32+3. [Architecture](#architecture)
33+4. [Connectors & data sources](#connectors--data-sources)
34+5. [API & routes](#api--routes)
35+6. [Canonical unit types](#canonical-unit-types-english)
36+7. [Run](#run)
37+8. [Tests](#tests)
38+9. [Deployment](#deployment)
39+10. [Development workflow (remote-first)](#development-workflow-remote-first)
40+11. [Expansion playbook](#expansion-playbook)
41+12. [The ·KA ecosystem](#the-ka-ecosystem)
42+13. [Contact](#contact)
43+
44+---
45+
46+## Guided tour
47+
48+Ten screenshots of the production site (captured 2026-08-28, live at
49+[www.rent-ka.com](https://www.rent-ka.com)).
50+
51+### 1 — Home page
52+
53+![Home page](docs/screenshots/01-accueil.jpg)
54+
55+The landing page: live counters (rentals indexed, sources, last sync, average
56+rent), a **Browse by province** grid covering every province and territory
57+outside Québec (Ontario, Alberta, British Columbia, Manitoba, Saskatchewan,
58+Nova Scotia, New Brunswick, PEI, Newfoundland and Labrador, NWT, Nunavut), a
59+city search box, and the ticker of per-province listing counts. The cookie
60+banner reflects the no-tracker policy: preferences live in `localStorage`
61+only.
62+
63+### 2 — Listing page (price analysis)
64+
65+![Listing page](docs/screenshots/02-listing.jpg)
66+
67+A listing detail page (`/listing/{uid}`): photo gallery with thumbnails,
68+advertised price, and the **Rent-Ka price analysis** panel — estimated fair
69+value with a confidence range, deviation vs the market ("Above market +8 %"),
70+a histogram of comparable listings, and the **Listing history** card (tracked
71+since, days online, observed price changes). The fair-value estimate is
72+computed continuously from comparable market listings.
73+
74+### 3 — Rental market statistics
75+
76+![Stats dashboard](docs/screenshots/03-stats.jpg)
77+
78+The `/stats` observatory: active listings, new/removed listings over the
79+selected period, average and median rent, quality quarantine size,
80+below-market listings, active connectors and covered cities — with period
81+presets (today → all), gauge charts for data-quality KPIs (geocoded share,
82+average record completeness…) and downloadable **PDF reports** (full report,
83+themed reports, custom report builder).
84+
85+### 4 — Aggregated sources registry
86+
87+![Sources registry](docs/screenshots/04-sources.jpg)
88+
89+The public `/sources` page: every property manager and platform tracked by
90+Rent-Ka, with connection status, active listing count and last sync time —
91+REALTOR.ca broker listings, Cogir, CAPREIT, Minto, Realstar, Hazelview and
92+hundreds more. Transparency is a core Groupe KA principle: each "connected"
93+source is synced periodically by a dedicated connector.
94+
95+### 5 — Privacy
96+
97+![Privacy page](docs/screenshots/05-privacy.jpg)
98+
99+"Your privacy, kept simple": no advertising pixel, no third-party cookies, no
100+data resale. The only browser storage is `localStorage` for consent, search
101+filters and list/map preference. Written in plain English with a
102+Loi 25-compliant contact for the responsible person.
103+
104+### 6 — Terms of use
105+
106+![Terms page](docs/screenshots/06-terms.jpg)
107+
108+The `/terms` page states what Rent-Ka is (an independent aggregator that
109+links back to the original ad) and what it is not (a landlord, a broker or a
110+party to any rental transaction), plus indexing-robots transparency.
111+
112+### 7 — Property manager profile
113+
114+![Manager profile](docs/screenshots/07-g-accommod8u.jpg)
115+
116+Public manager pages (`/g/{source_id}`, here Accommod8u): all active rentals
117+by that manager with photos, prices and unit types — plus (see capture 8) an
118+automatically matched Google Business profile with review statistics.
119+
120+### 8 — Listing page (details & manager panel)
9 121
10−Rent-Ka continuously aggregates rental listings published by Canadian 122+![Listing details](docs/screenshots/08-listing-details.jpg)
11−property managers, REITs and national portals: every listing keeps its 123+
12−photos, price, availability and a direct link to the original ad. 124+Further down a listing page: normalized characteristics (unit type,
125+availability date, pets, area), description with a link to the source's
126+original text, amenities, practical details, the PDF listing sheet download,
127+and the **"Who manages this rental?"** panel — manager profile matched to
128+Google Maps with rating, review distribution and recent excerpts, including
129+the confidence score of the automatic match.
130+
131+### 9 — Map view (Ka Maps)
132+
133+![Map view](docs/screenshots/09-accueil.jpg)
134+
135+The split list/map view (`/?view=map`), powered by the shared
136+**@groupe-ka/ka-maps** framework (Mapbox): clustered markers across the whole
137+country, price labels, "search as I move the map", 3D toggle and drawing
138+tools. The list panel stays in sync with the viewport.
139+
140+### 10 — Contact
141+
142+![Contact page](docs/screenshots/10-contact.jpg)
143+
144+The `/contact` page: Groupe KA addresses (projects & data partnerships, media,
145+legal/privacy), the aggregator disclaimer, and links to the 16 sites of the
146+·KA ecosystem.
147+
148+---
149+
150+## Features
151+
152+- **Search & browse** — full-text search, facet filters (city, unit type,
153+ price range, availability), browse by province and by city, list or map
154+ view, sort by recency/price.
155+- **Map** — Ka Maps (Mapbox GL) with clustering, price pins, viewport-synced
156+ list, polygon drawing and 3D buildings.
157+- **Listing pages** — photo gallery, normalized attributes, description,
158+ amenities, direct link to the original ad, downloadable PDF sheet,
159+ SEO-friendly server-rendered fallback.
160+- **Fair rental value** — continuous market-comparables model with range,
161+ deviation badge (above/below market) and confidence level.
162+- **Listing history & recycled-unit detection** — first-seen date, price
163+ changes observed across syncs, re-listed unit detection.
164+- **Manager profiles** — `/g/{source_id}` pages + automatic Google Business
165+ matching (rating, review histogram, recent excerpts, match confidence).
166+- **KA Scores** — OSM-based Walk / Transit / Bike / Quiet / Services scores,
167+ plus a Canada-appropriate **Winter Score**.
168+- **Data quality** — completeness scoring, publication gate, quarantine,
169+ photo audit (`imgcheck`), Québec-exclusion guard.
170+- **Statistics** — public `/stats` dashboard with period selector, KPI
171+ gauges, and PDF report generation (full, themed, custom).
172+- **KA ID** — optional Groupe KA single sign-on (email, Google, Apple) for
173+ saved favourites across the ecosystem; the site is fully usable signed out.
174+- **Privacy by design** — no trackers, no third-party cookies, no ads.
175+- **SEO** — server-side HTML rendering (meta, JSON-LD, breadcrumbs), robots
176+ and sitemap suite (`sitemap.xml`, pages/cities/listings sitemaps).
13 177
14 ## Architecture 178 ## Architecture
15 179
@@ -20,21 +184,16 @@ layer removed). The Python package is `rentka/`.
20 - **Backend** — FastAPI + SQLite (`data/rentka.db`): connectors → `ingest` 184 - **Backend** — FastAPI + SQLite (`data/rentka.db`): connectors → `ingest`
21 → geocoding (Nominatim) → dedup → `quality` (completeness score + 185 → geocoding (Nominatim) → dedup → `quality` (completeness score +
22 publication gate + Québec exclusion) → API. 186 publication gate + Québec exclusion) → API.
23−- **Connectors** (81) — three families: 187+- **Connector pipeline** — each source is a connector module under
24− - **Platform generators** (53): LiftSystem/Rentsync (`lift_*`), RentCafe 188+ `rentka/connectors/` (41 files) or a platform-registry entry (see below);
25− (`rc_*`), Rentsync gateway (`rsgw_*`), Buildium (`bld_*`), AppFolio 189+ `run.py sync` walks them, `run.py watch` loops every 60 minutes; every sync
26− (`apf_*`) — one JSON registry per platform in `data/*_clients.json`; 190+ is journaled (found/added/updated/removed + null-rate stats) and surfaced
27− adding a property manager anywhere in Canada = adding one client row 191+ on `/sources` and `/stats`.
28− (optional `"province"` key, default `"ON"`). 192+- **Frontend** — React/Vite (`frontend/`), **English (en-CA)**, cobalt skin
29− - **National landlords** (12): Boardwalk, CAPREIT, Centurion, Cogir, 193+ on the shared ka-ui tokens. Routes: `/`, `/listing/{uid}`,
30− Hazelview, InterRent, MetCap, Minto, Morguard, Realstar, Akelius, 194+ `/city/{slug}[/{type}]`, `/cities`, `/stats`, `/sources`, `/g/{source_id}`,
31− Killam… — whole portfolio outside Québec (AB/SK/BC/MB/NS/NB included). 195+ `/privacy`, `/terms`, `/contact`, `/doc`. Map = Ka Maps
32− - **National portals** (5): Rentals.ca, Zumper, Kijiji, Apartments.com, 196+ (`@groupe-ka/ka-maps`, expected at `../../ka-maps`).
33− Facebook Marketplace — major metros in every province.
34−- **Frontend** — React/Vite, **English (en-CA)**, cobalt skin. Routes: `/`,
35− `/listing/{uid}`, `/city/{slug}[/{type}]`, `/cities`, `/stats`,
36− `/sources`, `/privacy`, `/terms`. Map = Ka Maps (`@groupe-ka/ka-maps`,
37− expected at `../../ka-maps`).
38 - **SEO** — `rentka/seo.py` renders server-side HTML (meta, JSON-LD, 197 - **SEO** — `rentka/seo.py` renders server-side HTML (meta, JSON-LD,
39 sitemaps) in English. 198 sitemaps) in English.
40 - **Enrichment kept** (Canada-wide, no Québec dependency): KA Scores 199 - **Enrichment kept** (Canada-wide, no Québec dependency): KA Scores
@@ -46,6 +205,63 @@ layer removed). The Python package is `rentka/`.
46 gazquebec, quartier (QC census), real-cost breakdown, movers directory, 205 gazquebec, quartier (QC census), real-cost breakdown, movers directory,
47 the whole short-term subsystem, and ~300 QC connectors. 206 the whole short-term subsystem, and ~300 QC connectors.
48 207
208+## Connectors & data sources
209+
210+**767 registered connectors** (2026-08-28), three families:
211+
212+- **Platform generators** — one JSON registry per rental platform in
213+ `data/*_clients.json`; adding a property manager anywhere in Canada =
214+ adding one client row (optional `"province"` key, default `"ON"`):
215+ - **LiftSystem / Rentsync** (`lift_*`) — **640 clients**, the backbone of
216+ the manager coverage;
217+ - **Buildium** (`bld_*`) — 86 clients;
218+ - **RentCafe** (`rc_*`) — 26 clients;
219+ - **Rentsync gateway** (`rsgw_*`) — 7 clients (Fitzrovia, Drewlo, BGO…);
220+ - **AppFolio** (`apf_*`) — 2 clients.
221+- **National landlords & REITs** (dedicated connectors): Boardwalk, CAPREIT,
222+ Centurion, Cogir, Hazelview, InterRent, MetCap, Minto, Morguard, Realstar,
223+ Akelius, Killam, Skyline, Starlight, Homestead, Medallion, Q Residential,
224+ Greenrock, KG Group, Sifton, Westdale, RioCan Living… — whole portfolio
225+ outside Québec (AB/SK/BC/MB/NS/NB included).
226+- **National portals & MLS**: Rentals.ca, Zumper, Kijiji, Apartments.com,
227+ Facebook Marketplace, louer.ca — major metros in every province — plus
228+ **REALTOR.ca broker listings** (added 2026-08-28: CREA MLS rental listings
229+ via the internal PropertySearch API, recursive quad-split area scan,
230+ ~22,400 active rentals).
231+
232+Data quality per sync is tracked (null-price rate, null-address rate, missed
233+records) and gates publication; listings failing the completeness bar sit in
234+quarantine instead of being published.
235+
236+## API & routes
237+
238+Public JSON API (same origin, no key required for read endpoints):
239+
240+| Endpoint | Description |
241+|---|---|
242+| `GET /api/listings` | paginated search (city, source, type, price, sort…) |
243+| `GET /api/listings/{uid}` | one listing, full record |
244+| `GET /api/listings/{uid}/historique` | price/availability history |
245+| `GET /api/listings/{uid}/recyclees` | re-listed-unit detection |
246+| `GET /api/listings/{uid}/pdf` | listing sheet PDF |
247+| `GET /api/listings.geojson` | map payload (GeoJSON) |
248+| `GET /api/search` | unified list+map search (viewport, polygon) |
249+| `GET /api/facets` | facet counts for the filter bar |
250+| `GET /api/fairvalue/{uid}` | fair rental value estimate |
251+| `GET /api/kascores/stats` | KA Scores coverage stats |
252+| `GET /api/immeuble` | building passport lookup |
253+| `GET /api/managers/{source_id}` | manager profile (+ Google reviews) |
254+| `GET /api/sources` | source registry with sync status |
255+| `GET /api/stats` · `/api/stats/detailed` · `/api/stats/dashboard` | market statistics |
256+| `GET /api/stats/rapport.pdf` · `/api/stats/report[/custom]` | PDF reports |
257+| `GET /api/seo/cities` · `/api/seo/city/{slug}` | city directory data |
258+| `GET /api/img` | image proxy/cache |
259+
260+Server-rendered HTML routes for SEO: `/listing/{uid}`, `/city/{slug}[/{type}]`,
261+`/cities`, `/g/{source_id}`, `/sources`, `/stats`, `/privacy`, `/terms`,
262+`/doc`, `robots.txt` and the sitemap suite (`sitemap.xml`,
263+`sitemap-pages.xml`, `sitemap-cities.xml`, `sitemap-listings-{n}.xml`).
264+
49 ## Canonical unit types (English) 265 ## Canonical unit types (English)
50 266
51 `Studio | 1 bedroom | 2 bedrooms | 3 bedrooms | 4 bedrooms | 5+ bedrooms | 267 `Studio | 1 bedroom | 2 bedrooms | 3 bedrooms | 4 bedrooms | 5+ bedrooms |
@@ -66,8 +282,9 @@ python run.py geocode [n] # geocode listings missing coordinates
66 python run.py quality # recompute publication gate 282 python run.py quality # recompute publication gate
67 ``` 283 ```
68 284
69−pm2 (node M4M36): `rent-ka-web` (serve 8125) · `rent-ka-sync` (watch 60) · 285+Python dependencies: `requirements.txt` (use the repo's `.venv`). Frontend:
70−`rent-ka-ngrok` (`ngrok http --url=www.rent-ka.com 8125`). 286+`cd frontend && npm install && npm run build` (Ka Maps expected at
287+`../../ka-maps`).
71 288
72 ## Tests 289 ## Tests
73 290
@@ -78,10 +295,67 @@ python -m pytest tests/
78 Connector snapshot tests replay recorded fixtures (`tests/fixtures/`); 295 Connector snapshot tests replay recorded fixtures (`tests/fixtures/`);
79 re-record with `python run.py record <source>` after changing a connector. 296 re-record with `python run.py record <source>` after changing a connector.
80 297
298+## Deployment
299+
300+Production runs on the MacLustr node **M4M36** (Mac Studio), port **8125**,
301+under PM2:
302+
303+| PM2 process | Role |
304+|---|---|
305+| `rent-ka-web` | `run.py serve 8125` — API + frontend |
306+| `rent-ka-sync` | `run.py watch 60` — connector sync loop |
307+| `rent-ka-ngrok` | `ngrok http --url=www.rent-ka.com 8125` — public tunnel |
308+
309+PM2 resurrection is wired into launchd, so the three processes survive a
310+node reboot.
311+
312+## Development workflow (remote-first)
313+
314+The **source of truth is the git repo on the deployment node**
315+(`M4M36:~/apps/rent-ka`), not any laptop copy. Edits, builds, `pm2 restart`
316+and commits all happen on the node over SSH. The remote `origin` is
317+**spbgit** (Groupe KA's private git server, bare repos on the cluster
318+gateway; SSH alias `gitsrv`) — not GitHub. Pushes work during an SSH session
319+thanks to agent forwarding.
320+
81 ## Expansion playbook 321 ## Expansion playbook
82 322
83 The fastest way to add coverage is the platform registries: find property 323 The fastest way to add coverage is the platform registries: find property
84 managers whose sites run LiftSystem/RentCafe/Rentsync/Buildium/AppFolio 324 managers whose sites run LiftSystem/RentCafe/Rentsync/Buildium/AppFolio
85 (signatures documented in `gestion-immobiliere-ontario.md` §10) and append 325 (signatures documented in `gestion-immobiliere-ontario.md` §10) and append
86 a client entry with its `province`. `docs/canada-sources.md` tracks the 326 a client entry with its `province`. `docs/canada-sources.md` tracks the
87−national source inventory. 327+national source inventory. Per-connector documentation lives in
328+`docs/connecteurs/`.
329+
330+## The ·KA ecosystem
331+
332+Rent-Ka is one of the Groupe KA aggregators — fully automated platforms where
333+hundreds of connectors read sources directly, normalize the data and resync
334+on their own:
335+
336+[Groupe KA](https://www.groupe-ka.com) ·
337+[Lou-Ka](https://www.lou-ka.com) (Québec rentals) ·
338+[Rent-Ka](https://www.rent-ka.com) (Canada rentals) ·
339+[Immo-Ka](https://www.immo-ka.com) (Québec real estate) ·
340+[House-Ka](https://www.house-ka.com) (Canada homes for sale) ·
341+[Vrai-Prix](https://www.vrai-prix.com) ·
342+[Auto-Ka](https://www.auto-ka.com) ·
343+[Fabri-Ka](https://www.fabri-ka.com) ·
344+[Food-Ka](https://www.food-ka.com) ·
345+[Resto-Ka](https://www.resto-ka.com) ·
346+[Sorti-Ka](https://www.sorti-ka.com) ·
347+[Créa-Ka](https://www.crea-ka.com) ·
348+[Trouve-Ka](https://www.trouve-ka.com) ·
349+[Job-Ka](https://www.job-ka.com) ·
350+[API-Ka](https://www.api-ka.com) ·
351+[KA-Stats](https://www.ka-stats.com)
352+
353+## Contact
354+
355+- **Projects, partnerships & data** — contact@groupe-ka.com
356+- **Media & general questions** — info@groupe-ka.com
357+- **Legal, privacy & Loi 25** — admin@groupe-ka.com
358+- Author: Simon-Pierre Boucher — contact@spboucher.ai
359+
360+© 2026 Groupe KA — Rent-Ka is an independent aggregator: every listing links
361+back to the original ad.
added docs/screenshots/01-accueil.jpg +0 −0

Binary file not shown.

added docs/screenshots/02-listing.jpg +0 −0

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

added docs/screenshots/07-g-accommod8u.jpg +0 −0

Binary file not shown.

added docs/screenshots/08-listing-details.jpg +0 −0

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

Menu

Theme