SPB Git forge

spb/lou-ka

Public

Lou·Ka — tous les logements à louer du Québec, un seul endroit.

232commits 1branches 0releases
172.9 MBsize
maindefault branch
3 days agolast push
HTML 98.9% Python 0.6%

docs: README v3 — chiffres live vérifiés, pastilles dynamiques, sections complètes

Simon-Pierre Boucher committed 1 mo ago (Aug 24, 2026) parent 5b2bff8

1 changed file +144 −60

modified README.md +144 −60
@@ -6,25 +6,46 @@
6 6 <h1 align="center">Lou·Ka</h1>
7 7 <p align="center"><b>Tous les logements à louer</b></p>
8 8
9 −<p align="center">
10 − <a href="https://www.lou-ka.com"><img src="https://img.shields.io/website?url=https%3A%2F%2Fwww.lou-ka.com&style=flat-square&label=www.lou-ka.com&up_color=ff6a00&up_message=en%20ligne" alt="Site"></a>
11 − <a href="https://www.lou-ka.com/doc/"><img src="https://img.shields.io/badge/📖_documentation-%2Fdoc-ff6a00?style=flat-square" alt="Documentation"></a>
12 − <a href="https://www.lou-ka.com/doc/lou-ka-documentation.pdf"><img src="https://img.shields.io/badge/guide-PDF-ff6a00?style=flat-square" alt="PDF"></a>
13 − <img src="https://img.shields.io/badge/n%C5%93ud-M3U96b-1f6feb?style=flat-square" alt="Nœud">
14 − <img src="https://img.shields.io/badge/port-8095-141814?style=flat-square" alt="Port">
15 − <img src="https://img.shields.io/badge/process-PM2-2b037a?style=flat-square" alt="PM2">
16 −</p>
17 −<p align="center">
18 − <img src="https://img.shields.io/badge/Python-3.14-3776AB?style=flat-square&logo=python&logoColor=white" alt="Python">
19 − <img src="https://img.shields.io/badge/FastAPI-API_+_SSR-009688?style=flat-square&logo=fastapi&logoColor=white" alt="FastAPI">
20 − <img src="https://img.shields.io/badge/React_18-Vite_+_TS-087EA4?style=flat-square&logo=react&logoColor=white" alt="React">
21 − <img src="https://img.shields.io/badge/SQLite-WAL-003B57?style=flat-square&logo=sqlite&logoColor=white" alt="SQLite">
22 − <img src="https://img.shields.io/badge/Groupe-KA-ff6a00?style=flat-square" alt="Groupe KA">
23 −</p>
9 +<div align="center">
10 +
11 +<a href="https://www.lou-ka.com"><img src="https://img.shields.io/website?url=https%3A%2F%2Fwww.lou-ka.com&style=flat-square&label=www.lou-ka.com&up_color=ff6a00&up_message=en%20ligne" alt="Site"></a>
12 +<a href="https://www.lou-ka.com/doc/"><img src="https://img.shields.io/badge/📖_documentation-%2Fdoc-ff6a00?style=flat-square" alt="Documentation"></a>
13 +<a href="https://www.lou-ka.com/doc/lou-ka-documentation.pdf"><img src="https://img.shields.io/badge/guide-PDF-ff6a00?style=flat-square" alt="PDF"></a>
14 +<img src="https://img.shields.io/badge/n%C5%93ud-M3U96b-1f6feb?style=flat-square" alt="Nœud">
15 +<img src="https://img.shields.io/badge/port-8095-141814?style=flat-square" alt="Port">
16 +<img src="https://img.shields.io/badge/process-PM2-2b037a?style=flat-square" alt="PM2">
17 +
18 +</div>
19 +
20 +<div align="center">
21 +
22 +<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fwww.lou-ka.com%2Fapi%2Fstats&query=%24.total&label=annonces%20actives&color=ff6a00&style=flat-square" alt="Annonces actives (live)">
23 +<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fwww.lou-ka.com%2Fapi%2Fstats&query=%24.sources&label=sources%20actives&color=ff6a00&style=flat-square" alt="Sources actives (live)">
24 +<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fwww.lou-ka.com%2Fapi%2Fstats%2Fdetailed&query=%24.totals.cities&label=villes&color=ff6a00&style=flat-square" alt="Villes (live)">
25 +<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fwww.lou-ka.com%2Fapi%2Fstats%2Fdetailed&query=%24.totals.regions&label=r%C3%A9gions&color=ff6a00&style=flat-square" alt="Régions (live)">
26 +<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fwww.lou-ka.com%2Fapi%2Fstats%2Fdetailed&query=%24.totals.median&label=loyer%20m%C3%A9dian&suffix=%20%24&color=ff6a00&style=flat-square" alt="Loyer médian (live)">
27 +<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fwww.lou-ka.com%2Fapi%2Fstats%2Fdetailed&query=%24.totals.gps_pct&label=g%C3%A9olocalis%C3%A9es&suffix=%20%25&color=ff6a00&style=flat-square" alt="Géolocalisées (live)">
28 +<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fwww.lou-ka.com%2Fapi%2Fkascores%2Fstats&query=%24.couverture_pct&label=couverture%20KA%20Scores&suffix=%20%25&color=ff6a00&style=flat-square" alt="Couverture KA Scores (live)">
29 +<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fwww.lou-ka.com%2Fapi%2Fct%2Fstats&query=%24.total&label=s%C3%A9jours%20court%20terme&color=ff6a00&style=flat-square" alt="Séjours court terme (live)">
30 +
31 +</div>
32 +
33 +<div align="center">
34 +
35 +<img src="https://img.shields.io/badge/Python-3.14-3776AB?style=flat-square&logo=python&logoColor=white" alt="Python">
36 +<img src="https://img.shields.io/badge/FastAPI-API_+_SSR-009688?style=flat-square&logo=fastapi&logoColor=white" alt="FastAPI">
37 +<img src="https://img.shields.io/badge/React_18-Vite_+_TS-087EA4?style=flat-square&logo=react&logoColor=white" alt="React">
38 +<img src="https://img.shields.io/badge/SQLite-WAL-003B57?style=flat-square&logo=sqlite&logoColor=white" alt="SQLite">
39 +<img src="https://img.shields.io/badge/Mapbox_GL-ka--maps-000000?style=flat-square&logo=mapbox&logoColor=white" alt="Mapbox GL">
40 +<img src="https://img.shields.io/badge/tunnel-ngrok-1F1E37?style=flat-square&logo=ngrok&logoColor=white" alt="ngrok">
41 +<img src="https://img.shields.io/badge/Groupe-KA-ff6a00?style=flat-square" alt="Groupe KA">
42 +<a href="https://git.spboucher.ai"><img src="https://img.shields.io/badge/remote--first-spbgit-8250df?style=flat-square&logo=git&logoColor=white" alt="spbgit"></a>
43 +
44 +</div>
24 45
25 46 Chercher un appartement au Québec, c'est ouvrir des dizaines de sites différents — chacun avec sa navigation, ses filtres, son format. **Lou·Ka retourne le problème** : un **connecteur dédié par gestionnaire immobilier** visite chaque site, **normalise chaque annonce** vers un schéma unique et **détecte les changements en continu** (synchronisation périodique + hash de contenu → ajouts, mises à jour et retraits automatiques ; une annonce disparue répond `410 Gone`). Chaque fiche renvoie vers l'annonce originale du gestionnaire via une passerelle de sortie transparente (`/passerelle/{uid}`).
26 47
27 −Pour qui ? Les locataires qui cherchent (recherche filtrée, carte 3D, fiches complètes), les curieux du marché (observatoire des loyers, rapports PDF) et les gestionnaires (pages réclamables). **En chiffres** : 22 900+ annonces actives, 265 sources recensées, 212 connecteurs, 820 villes, 11 régions, ~70 % des annonces géolocalisées.
48 +Pour qui ? Les locataires qui cherchent (recherche filtrée, carte 3D, fiches complètes), les curieux du marché (observatoire des loyers, rapports PDF) et les gestionnaires (pages réclamables). **En chiffres (au 2026-08-24)** : 45 762 annonces actives publiées, 281 sources recensées, 250 connecteurs (221 location long terme + 29 court terme), 1 233 villes, 11 régions, 97,4 % des annonces géolocalisées, loyer médian 1 700 $ — plus **41 460 séjours court terme** (chalets, Airbnb…) dans la section `/court-terme`.
28 49
29 50 ## Visite guidée
30 51
@@ -82,33 +103,48 @@ Pour qui ? Les locataires qui cherchent (recherche filtrée, carte 3D, fiches co
82 103 - **Recherche filtrée** — ville, quartier, type (3½, 4½…), loyer min/max, animaux, meublé, superficie, texte libre.
83 104 - **Vue carte 3D** — Lou-Ka Maps (framework `@groupe-ka/ka-maps`, moteur Mapbox GL JS) : clusters par prix moyen, « Rechercher dans cette zone », bascule 3D/2D, synchro liste ↔ carte.
84 105 - **Fiches complètes** — toutes les photos, digest structuré de la description (text mining regex FR, aucun LLM), badge marché, historique de prix (`price_log`), fiche PDF avec QR code.
85 −- **Couches de données de quartier** — recensement 2021, registre des loyers, inondation (BDZI), criminalité (SPVM), qualité de l'air, prix de l'essence, commerces et transport en commun, estimation Hydro-Québec, **KA Scores**.
106 +- **Couches de données de quartier** — recensement 2021, registre des loyers (57 433 déclarations géocodées), inondation (BDZI), criminalité (SPVM, 12 mois par catégorie), qualité de l'air (RSQAQ/PST), prix de l'essence, commerces et transport en commun (métro/REM aux couleurs officielles), estimation Hydro-Québec live, **KA Scores** (95,5 % du parc couvert au 2026-08-24).
107 +- **Location court terme** — section isolée `/court-terme` (sous-système `louka/shortterm/`, API `/api/ct/*`) : chalets, Airbnb (quadrillage carte quadtree limité à la frontière du Québec), Vrbo, Booking… 41 460 séjours, 22 sources actives sur 38 recensées, 27 régions (au 2026-08-24) ; SEO complet (JSON-LD `VacationRental`, sitemaps `sitemap-ct-N.xml`).
86 108 - **Pages villes SEO** — `/villes`, `/ville/{slug}`, `/ville/{slug}/{type}` en SSR léger, sitemaps dynamiques (chunks de 10 000), JSON-LD (`RealEstateListing` + `Offer` CAD), vrais `404`/`410`.
87 −- **Observatoire du marché** — KPI temps réel, loyers médians par région/ville/taille, rapport de marché PDF multi-pages (`/api/stats/rapport.pdf`).
88 −- **Registre des sources** — chaque gestionnaire, son statut, sa dernière synchro ; toute source non connectable est documentée avec sa raison dans `data/sources.json`.
109 +- **Observatoire du marché** — KPI temps réel, loyers médians par région/ville/taille, panneaux territoire (registre des loyers, population, essence), rapport de marché PDF multi-pages (`/api/stats/rapport.pdf`) et rapports PDF personnalisés (catalogue + `ReportBuilder`).
110 +- **Registre des sources** — chaque gestionnaire, son statut, sa dernière synchro ; toute source non connectable est documentée avec sa raison dans `data/sources.json` (281 entrées recensées).
111 +- **Qualité éditoriale** — porte de pertinence (quarantaine des stationnements, garages, locaux commerciaux, locations à la nuit) : 59 668 annonces publiées / 1 175 en quarantaine, complétude moyenne 91,4 % (au 2026-08-24).
89 112 - **Comptes & SSO KA** — « Se connecter avec KA » via le hub groupe-ka.com (JWT HS256, `ka_id` émis par le hub) + Google OAuth direct ; favoris synchronisés vers « Mon univers Ka » ; pages gestionnaires réclamables (`/g/{source_id}`).
90 −- **Widget KA Agent** — bulle de chat IA du Groupe KA intégrée au site.
113 +- **Widget KA Agent** — bulle de chat IA du Groupe KA intégrée au site (déplaçable, position mémorisée).
91 114 - **PWA installable** + app iOS SwiftUI 100 % native (dépôt séparé `lou-ka-ios` sur spbgit).
92 −- **Robustesse** — garde-fou anti-dérive (`DRIFT_RATIO = 0.25`) : si une source retourne soudainement beaucoup moins d'annonces, les retraits sont suspendus au lieu de vider l'inventaire.
115 +- **Robustesse** — garde-fou anti-dérive (`DRIFT_RATIO = 0.25`, `louka/db.py`) : si une source retourne soudainement beaucoup moins d'annonces, les retraits sont suspendus au lieu de vider l'inventaire ; chaîne de fetch anti-bot résiliente (Oxylabs → Scrapfly → Bright Data).
93 116
94 117 ## API (endpoints principaux)
95 118
96 119 Servis par `louka/web.py` (FastAPI) sur le port 8095.
97 120
98 −| Endpoint | Rôle |
99 −|---|---|
100 −| `GET /api/search` | recherche unifiée liste ↔ carte (mêmes filtres, même compteur) |
101 −| `GET /api/listings` · `GET /api/listings/{uid}` | annonces paginées + fiche détaillée (`410 Gone` si retirée) |
102 −| `GET /api/listings.geojson` | flux GeoJSON pour la carte 3D |
103 −| `GET /api/listings/{uid}/pdf` | fiche PDF avec QR code |
104 −| `GET /api/facets` · `GET /api/sources` | facettes de filtres, registre des sources |
105 −| `GET /api/fairvalue/{uid}` | badge marché (juste prix) d'une annonce |
106 −| `GET /api/rdl` · `/api/inondation` · `/api/air` · `/api/gaz` · `/api/commerces` · `/api/hydro` | couches de quartier : registre des loyers, BDZI, qualité de l'air, essence, commerces/transport, estimation Hydro-Québec |
107 −| `GET /api/kascores/stats` | statistiques du moteur KA Scores |
108 −| `GET /api/stats` · `/detailed` · `/dashboard` · `/report` · `/catalog` · `POST /api/stats/report/custom` | observatoire + rapports PDF (catalogue et personnalisés) |
109 −| `GET /api/stats/rapport.pdf` | rapport de marché PDF multi-pages |
110 −| `POST /api/sync` | déclenchement d'une synchronisation |
111 −| `GET /doc/` | guide d'utilisation en ligne |
121 +### Location long terme
122 +
123 +| Méthode | Endpoint | Rôle |
124 +|---|---|---|
125 +| `GET` | `/api/search` | recherche unifiée liste ↔ carte (mêmes filtres, même compteur) |
126 +| `GET` | `/api/listings` · `/api/listings/{uid}` | annonces paginées + fiche détaillée (`410 Gone` si retirée) |
127 +| `GET` | `/api/listings.geojson` | flux GeoJSON pour la carte 3D |
128 +| `GET` | `/api/listings/{uid}/pdf` | fiche PDF avec QR code |
129 +| `GET` | `/api/facets` · `/api/sources` | facettes de filtres, registre des sources |
130 +| `GET` | `/api/fairvalue/{uid}` | badge marché (juste prix) d'une annonce |
131 +| `GET` | `/api/rdl` · `/api/inondation` · `/api/air` · `/api/gaz` · `/api/commerces` · `/api/hydro` | couches de quartier : registre des loyers, BDZI, qualité de l'air, essence, commerces/transport, estimation Hydro-Québec |
132 +| `GET` | `/api/kascores/stats` | statistiques du moteur KA Scores |
133 +| `GET` | `/api/stats` · `/detailed` · `/dashboard` · `/report` · `/catalog` | observatoire : KPI, détail, tableau de bord, rapports |
134 +| `POST` | `/api/stats/report/custom` | rapport PDF personnalisé (ReportBuilder) |
135 +| `GET` | `/api/stats/rapport.pdf` | rapport de marché PDF multi-pages |
136 +| `POST` | `/api/sync` | déclenchement d'une synchronisation |
137 +| `GET` | `/doc/` | guide d'utilisation en ligne |
138 +
139 +### Location court terme (`/api/ct`, préfixe du sous-système `louka/shortterm/`)
140 +
141 +| Méthode | Endpoint | Rôle |
142 +|---|---|---|
143 +| `GET` | `/api/ct/listings` · `/api/ct/listings/{uid}` | séjours paginés + fiche détaillée |
144 +| `GET` | `/api/ct/listings.geojson` | flux GeoJSON de la carte court terme |
145 +| `GET` | `/api/ct/facets` · `/api/ct/sources` | facettes, registre des sources court terme |
146 +| `GET` | `/api/ct/stats` | KPI court terme (total, sources, régions, prix/nuit) |
147 +| `POST` | `/api/ct/sync` | déclenchement d'une synchronisation court terme |
112 148
113 149 ## Architecture
114 150
@@ -116,36 +152,96 @@ Pipeline : **connecteurs → normalisation → déduplication → SQLite → API
116 152
117 153 - **Backend Python 3.14 / FastAPI / Uvicorn** (`louka/web.py`) : API JSON + service du build Vite + SSR SEO (`louka/seo.py`).
118 154 - **SQLite (WAL)** (`louka/db.py`) : migrations auto, upsert par hash de contenu, anti-dérive ; bases annexes dans `data/` (quartier, air, gaz, hydro, commerces, inondation…).
119 −- **212 connecteurs** auto-découverts (`louka/connectors/`), extraction directe / Firecrawl / Scrapfly selon la source.
155 +- **250 connecteurs** auto-découverts : 221 long terme (`louka/connectors/`) + 29 court terme (`louka/shortterm/connectors/`), extraction directe / Firecrawl / Scrapfly / Bright Data / acteurs Apify maison selon la source.
120 156 - **Enrichissement** : géocodage (Nominatim + Adresses Québec), POI OSM, stats de quartier, KA Scores, estimation Hydro-Québec.
121 157 - **Frontend React 18 + Vite + TypeScript** (`frontend/`), cartographie `@groupe-ka/ka-maps` (Mapbox GL).
122 −- **CLI `run.py`** : `sync` · `watch` · `serve` · `geocode` · `poi` · `quartier` · `record` (fixtures HTTP pour tests hors-ligne).
158 +- **CLI `run.py`** : `sync` · `watch` · `sync-ct` · `watch-ct` · `serve` · `geocode` · `quality` · `imgaudit` · `fairvalue` · `poi` · `quartier` · `kascores` · `rdl` · `air-refresh` · `gaz-refresh` · `hydro-precompute` · `record` (fixtures HTTP pour tests hors-ligne).
123 159
124 160 Processus PM2 sur le nœud :
125 161
126 −| Processus | Rôle | Cadence |
127 −|---|---|---|
128 −| `lou-ka-web` | serveur FastAPI/Uvicorn (API + frontend + SSR) sur le port **8095** | continu |
129 −| `lou-ka-sync` | boucle de resynchronisation des connecteurs (`run.py watch 60`) | cycle de 60 min |
130 −| `lou-ka-ngrok` | tunnel ngrok vers **www.lou-ka.com** | continu |
162 +| Processus | Commande réelle | Rôle | Cadence |
163 +|---|---|---|---|
164 +| `lou-ka-web` | `.venv/bin/python run.py serve 8095` | serveur FastAPI/Uvicorn (API + frontend + SSR) sur le port **8095** | continu |
165 +| `lou-ka-sync` | `.venv/bin/python run.py watch 60` | boucle de resynchronisation des connecteurs long terme | cycle de 60 min |
166 +| `lou-ka-ngrok` | `ngrok http --url=www.lou-ka.com 8095` | tunnel ngrok vers **www.lou-ka.com** | continu |
167 +
168 +La section court terme se resynchronise via `run.py watch-ct` (défaut 360 min) ou à la demande (`run.py sync-ct`, `POST /api/ct/sync`).
169 +
170 +## Démarrage rapide
131 171
132 −Points de configuration notables (variables d'environnement, sans secrets dans le repo) : clés Scrapfly/Firecrawl pour certains connecteurs, jeton Mapbox du frontend, secret SSO partagé avec le hub KA ID. Le registre des sources vit dans `data/sources.json` ; les bases SQLite de prod sont gitignorées.
172 +```bash
173 +# Backend (Python 3.14)
174 +python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
175 +
176 +# Frontend (nécessite le framework ka-maps bâti à côté : ../ka-maps)
177 +cd frontend && npm install && npm run build && cd ..
178 +
179 +.venv/bin/python run.py sync # ingestion (toutes les sources ou une liste)
180 +.venv/bin/python run.py sync-ct # ingestion court terme
181 +.venv/bin/python run.py serve 8095 # API + frontend sur http://localhost:8095
182 +.venv/bin/python run.py watch 60 # resynchronisation en boucle (minutes)
183 +
184 +# Tests (pytest + fixtures HTTP rejouables hors-ligne)
185 +.venv/bin/python -m pytest tests/
186 +```
187 +
188 +En développement frontend : `cd frontend && npm run dev` (Vite sur `:5173`, proxy `/api`).
189 +
190 +## Variables d'environnement
191 +
192 +Aucun secret dans le repo — tout passe par l'environnement du nœud. Noms attendus :
193 +
194 +| Variable | Rôle |
195 +|---|---|
196 +| `SCRAPFLY_KEY` · `FIRECRAWL_API_KEY` · `APIFY_TOKEN` | extraction anti-bot / rendu / acteurs Apify maison |
197 +| `BRIGHTDATA_API_KEY` · `BRIGHTDATA_ZONE` | Web Unlocker Bright Data (repli anti-bot) |
198 +| `OXYLABS_PROXY` · `OXYLABS_PROXY_USER` · `OXYLABS_PROXY_PASS` | proxies résidentiels (1er maillon de la chaîne de fetch) |
199 +| `GOOGLE_CLIENT_ID` · `GOOGLE_CLIENT_SECRET` | connexion Google OAuth directe |
200 +| `KA_SSO_SECRET` · `KA_HUB_URL` · `SESSION_SECRET` | SSO KA ID (JWT HS256 partagé avec groupe-ka.com) + sessions |
201 +| `HQ_CAPTCHA_PROVIDER` · `HQ_CAPTCHA_KEY` | résolution reCAPTCHA de l'estimation Hydro-Québec |
202 +| `LOUKA_BASE_URL` | URL publique de base (liens PDF, sitemaps) |
203 +| `LOUKA_<SOURCE>_*` (≈70 variables) | tuning par connecteur : limites de détail, TTL, pages max, cadence (ex. `LOUKA_KIJIJI_DETAIL_LIMIT`, `LOUKA_FBMP_CITIES`, `LOUKA_AIRBNB_BUDGET`) |
204 +| `VITE_MAPBOX_TOKEN` (frontend) | jeton public Mapbox de la carte 3D |
205 +
206 +## Données & conformité
207 +
208 +- **Agrégateur indépendant** : aucune affiliation avec les gestionnaires immobiliers ; chaque fiche renvoie vers l'annonce originale via la passerelle de sortie transparente `/passerelle/{uid}` (mention affichée au pied du site).
209 +- **Provenance** : sites publics des gestionnaires et portails d'annonces (281 sources recensées dans `data/sources.json`, statut et raison documentés pour chaque source non connectable) ; couches de quartier issues de données ouvertes (recensement 2021, registre des loyers, BDZI, SPVM, RSQAQ, Régie de l'énergie, OSM).
210 +- **Cadence** : resynchronisation long terme en boucle de 60 min (`lou-ka-sync`), court terme par cycles de 360 min ; détection de changement par hash de contenu → ajouts, mises à jour et retraits automatiques.
211 +- **Cycle de vie honnête** : une annonce retirée chez la source répond `410 Gone` et sort des sitemaps ; le garde-fou anti-dérive suspend les retraits massifs suspects plutôt que de vider l'inventaire.
212 +- **Qualité** : porte de pertinence (quarantaine du hors-périmètre : stationnements, commerciaux, nuitées) et score de complétude par annonce (moyenne 91,4 %).
133 213
134 214 ## Structure du repo
135 215
136 216 ```
137 217 lou-ka/
138 −├── run.py # point d'entrée CLI (sync / watch / serve / geocode / poi / quartier / record)
139 −├── louka/ # paquet backend : web, seo, db, ingest, normalize, textmine, auth, kascores… + connectors/ (212)
218 +├── run.py # point d'entrée CLI (sync / watch / sync-ct / watch-ct / serve / geocode / poi / quartier / record)
219 +├── louka/ # paquet backend : web, seo, db, ingest, normalize, textmine, auth, kascores…
220 +│ ├── connectors/ # 221 connecteurs long terme auto-découverts
221 +│ └── shortterm/ # sous-système court terme isolé (db, ingest, web + 29 connecteurs)
140 222 ├── frontend/ # React 18 + Vite + TypeScript (pages, composants, kamaps/) + public/doc/ (guide)
141 −├── data/ # sources.json (registre) + bases SQLite de prod (gitignorées)
142 −├── scripts/ # build recensement/contexte/environnement, screenshots, check-order
223 +├── data/ # sources.json (registre, 281 entrées) + bases SQLite de prod (gitignorées)
224 +├── scripts/ # build recensement/contexte/environnement, docs connecteurs, screenshots, check-order
143 225 ├── tests/ # pytest + fixtures HTTP rejouables hors-ligne
144 −├── actors/ # acteurs Apify d'appoint
226 +├── actors/ # acteurs Apify d'appoint (ka-fb-marketplace, ka-apartments-com…)
145 227 ├── reports/ # audits (fiches connecteurs, expansion par région, quartier…)
146 228 └── docs/ # captures d'écran + docs connecteurs + ka-maps
147 229 ```
148 230
231 +## Historique
232 +
233 +Repère des jalons (128 commits depuis la naissance) :
234 +
235 +| Date | Jalon |
236 +|---|---|
237 +| 2026-08-06 | naissance du projet : agrégateur Québec/Lévis/Grand Montréal, page Statistiques (`fb48938`, `ece6ed0`) |
238 +| 2026-08-08 | Mission 1a — couche commune : schéma enrichi, normalisation centrale, robustesse, tests (`7323079`) |
239 +| 2026-08-19 | KA Scores calculés sur 94,7 % du parc + standard « ordre des sections = ordre du DOM » (`747f631`, `a6e30ef`) |
240 +| 2026-08-21→22 | porte de pertinence (quarantaine hors-périmètre) + chaîne de fetch anti-bot Oxylabs→Scrapfly→Bright Data + acteurs Apify maison FB Marketplace / Apartments.com (`8547737`, `8598785`, `e7f4876`) |
241 +| 2026-08-22→23 | section « Location court terme » : sous-système isolé, Airbnb en quadrillage carte, 38 sources recensées, SEO complet (`38b708b`, `5c571bc`, `63456a0`) |
242 +| 2026-08-23 | couches de quartier : registre des loyers (57 433 déclarations), inondation BDZI, criminalité SPVM, air, essence, commerces/transport, estimation Hydro-Québec live + rapports PDF personnalisés (`604455e` → `4d17c17`, `834c92c`) |
243 +| 2026-08-24 | page documentation `/doc` + guide PDF + README v2/v3 (`963ba8f`, `4fa8714`) |
244 +
149 245 ## Documentation
150 246
151 247 - **Guide en ligne** : [www.lou-ka.com/doc/](https://www.lou-ka.com/doc/) — à quoi sert le site, le parcours en 4 étapes (recherche → résultats → fiche → /stats), d'où viennent les données, FAQ.
@@ -160,21 +256,9 @@ lou-ka/
160 256 - L'agent forwarding SSH est actif : le `git push origin main` fonctionne pendant une session SSH depuis le laptop.
161 257
162 258 ```bash
163 −# Backend
164 −python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
165 −
166 −# Frontend (nécessite le framework ka-maps bâti à côté : ../ka-maps)
167 −cd frontend && npm install && npm run build && cd ..
168 −
169 −.venv/bin/python run.py sync # ingestion (toutes les sources ou une liste)
170 −.venv/bin/python run.py serve 8095 # API + frontend
171 −.venv/bin/python run.py watch 60 # resynchronisation en boucle (minutes)
172 −
173 259 pm2 restart lou-ka-web # après un changement en production
174 260 ```
175 261
176 −En développement frontend : `cd frontend && npm run dev` (Vite sur `:5173`, proxy `/api`).
177 −
178 262 ## Déploiement
179 263
180 264 - **Nœud** : M3U96b (Mac Studio, cluster MacLustr) — répertoire `~/apps/lou-ka`
181 265