docs: README v2 — galerie multi-pages, style du site, documentation, contact
1 changed file +123 −38
modified
README.md
+123 −38
@@ -1,30 +1,81 @@ | |||||
| 1 | <!-- Auteur : Simon-Pierre Boucher — contact@spboucher.ai --> | 1 | <!-- Auteur : Simon-Pierre Boucher — contact@spboucher.ai --> | ||
| 2 | 2 | ||||
| 3 | −# Lou·Ka | 3 | +<p align="center"> | ||
| 4 | − | 4 | + <a href="https://www.lou-ka.com"><img src="https://www.lou-ka.com/og.png" width="760" alt="Lou·Ka — Tous les logements à louer"></a> | ||
| 5 | −**Tous les logements à louer du Québec, agrégés au même endroit — un index fidèle, sans prix inventé ni coordonnée devinée.** | 5 | +</p> | ||
| 6 | − | 6 | +<h1 align="center">Lou·Ka</h1> | ||
| 7 | −[](https://www.lou-ka.com) | 7 | +<p align="center"><b>Tous les logements à louer</b></p> | ||
| 8 | − | ||||
| 9 | − | ||||
| 10 | − | ||||
| 11 | 8 | ||||
| 12 | − | 9 | +<p align="center"> | ||
| 13 | − | 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> | ||
| 14 | − | 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> | ||
| 15 | − | 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> | ||
| 16 | − | 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> | ||||
| 17 | 24 | ||||
| 18 | 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}`). | 25 | 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}`). | ||
| 19 | 26 | ||||
| 20 | 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. | 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. | ||
| 21 | 28 | ||||
| 22 | −## Captures d'écran | 29 | +## Visite guidée | ||
| 23 | − | 30 | + | ||
| 24 | −<p align="center"> | 31 | +<table> | ||
| 25 | − <img src="docs/screenshots/lou-ka-desktop.png" width="640" alt="Accueil — desktop"> | 32 | + <tr> | ||
| 26 | − <img src="docs/screenshots/lou-ka-mobile.png" width="200" alt="Accueil — mobile"> | 33 | + <td align="center"><img src="docs/screenshots/lou-ka-desktop.png" width="420"><br><sub><b>Accueil — recherche et univers Lou·Ka (desktop)</b></sub></td> | ||
| 27 | −</p> | 34 | + <td align="center"><img src="docs/screenshots/lou-ka-mobile.png" width="220"><br><sub><b>Accueil — version mobile</b></sub></td> | ||
| 35 | + </tr> | ||||
| 36 | + <tr> | ||||
| 37 | + <td align="center"><img src="frontend/public/doc/img/etape1.png" width="420"><br><sub><b>Étape 1 · Cherchez depuis l'accueil</b></sub></td> | ||||
| 38 | + <td align="center"><img src="frontend/public/doc/img/etape2.png" width="420"><br><sub><b>Étape 2 · Parcourez les résultats d'une ville</b></sub></td> | ||||
| 39 | + </tr> | ||||
| 40 | + <tr> | ||||
| 41 | + <td align="center"><img src="frontend/public/doc/img/etape3.png" width="420"><br><sub><b>Étape 3 · Ouvrez la fiche d'un logement</b></sub></td> | ||||
| 42 | + <td align="center"><img src="frontend/public/doc/img/etape4.png" width="420"><br><sub><b>Étape 4 · Suivez le marché sur /stats</b></sub></td> | ||||
| 43 | + </tr> | ||||
| 44 | + <tr> | ||||
| 45 | + <td align="center"><img src="docs/screenshots/annonces.jpg" width="420"><br><sub><b>Résultats de recherche — liste d'annonces filtrée</b></sub></td> | ||||
| 46 | + <td align="center"><img src="docs/screenshots/carte.jpg" width="420"><br><sub><b>Vue carte 3D — clusters par prix moyen (ka-maps)</b></sub></td> | ||||
| 47 | + </tr> | ||||
| 48 | + <tr> | ||||
| 49 | + <td align="center"><img src="docs/screenshots/fiche-logement.jpg" width="420"><br><sub><b>Fiche logement — photos, digest, badge marché, quartier</b></sub></td> | ||||
| 50 | + <td align="center"><img src="docs/screenshots/sources.png" width="420"><br><sub><b>Registre des sources — chaque gestionnaire et sa synchro</b></sub></td> | ||||
| 51 | + </tr> | ||||
| 52 | + <tr> | ||||
| 53 | + <td align="center"><img src="docs/screenshots/villes.jpg" width="420"><br><sub><b>Répertoire des villes (pages SEO)</b></sub></td> | ||||
| 54 | + <td align="center"><img src="docs/screenshots/ville-quebec.jpg" width="420"><br><sub><b>Page ville — Québec</b></sub></td> | ||||
| 55 | + </tr> | ||||
| 56 | + <tr> | ||||
| 57 | + <td align="center"><img src="docs/screenshots/stats.png" width="420"><br><sub><b>Observatoire du marché — loyers médians, KPI</b></sub></td> | ||||
| 58 | + <td align="center"><img src="docs/screenshots/accueil.png" width="420"><br><sub><b>Accueil — variante pleine page</b></sub></td> | ||||
| 59 | + </tr> | ||||
| 60 | + <tr> | ||||
| 61 | + <td align="center" colspan="2"><img src="docs/screenshots/accueil-mobile.png" width="220"><br><sub><b>Accueil mobile — variante pleine page</b></sub></td> | ||||
| 62 | + </tr> | ||||
| 63 | +</table> | ||||
| 64 | + | ||||
| 65 | +### App iOS native | ||||
| 66 | + | ||||
| 67 | +<table> | ||||
| 68 | + <tr> | ||||
| 69 | + <td align="center"><img src="docs/screenshots/ios/accueil.jpg" width="180"><br><sub><b>Accueil</b></sub></td> | ||||
| 70 | + <td align="center"><img src="docs/screenshots/ios/decouverte.jpg" width="180"><br><sub><b>Découverte</b></sub></td> | ||||
| 71 | + <td align="center"><img src="docs/screenshots/ios/carte.jpg" width="180"><br><sub><b>Carte</b></sub></td> | ||||
| 72 | + </tr> | ||||
| 73 | + <tr> | ||||
| 74 | + <td align="center"><img src="docs/screenshots/ios/fiche.jpg" width="180"><br><sub><b>Fiche logement</b></sub></td> | ||||
| 75 | + <td align="center"><img src="docs/screenshots/ios/stats.jpg" width="180"><br><sub><b>Statistiques</b></sub></td> | ||||
| 76 | + <td align="center"><img src="docs/screenshots/ios/sources.jpg" width="180"><br><sub><b>Sources</b></sub></td> | ||||
| 77 | + </tr> | ||||
| 78 | +</table> | ||||
| 28 | 79 | ||||
| 29 | ## Fonctionnalités | 80 | ## Fonctionnalités | ||
| 30 | 81 | ||||
@@ -40,6 +91,25 @@ Pour qui ? Les locataires qui cherchent (recherche filtrée, carte 3D, fiches co | |||||
| 40 | - **PWA installable** + app iOS SwiftUI 100 % native (dépôt séparé `lou-ka-ios` sur spbgit). | 91 | - **PWA installable** + app iOS SwiftUI 100 % native (dépôt séparé `lou-ka-ios` sur spbgit). | ||
| 41 | - **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. | 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. | ||
| 42 | 93 | ||||
| 94 | +## API (endpoints principaux) | ||||
| 95 | + | ||||
| 96 | +Servis par `louka/web.py` (FastAPI) sur le port 8095. | ||||
| 97 | + | ||||
| 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 | | ||||
| 112 | + | ||||
| 43 | ## Architecture | 113 | ## Architecture | ||
| 44 | 114 | ||||
| 45 | Pipeline : **connecteurs → normalisation → déduplication → SQLite → API/SSR/frontend**. | 115 | Pipeline : **connecteurs → normalisation → déduplication → SQLite → API/SSR/frontend**. | ||
@@ -53,11 +123,13 @@ Pipeline : **connecteurs → normalisation → déduplication → SQLite → API | |||||
| 53 | 123 | ||||
| 54 | Processus PM2 sur le nœud : | 124 | Processus PM2 sur le nœud : | ||
| 55 | 125 | ||||
| 56 | −| Processus | Rôle | | 126 | +| Processus | Rôle | Cadence | | ||
| 57 | −|---|---| | 127 | +|---|---|---| | ||
| 58 | −| `lou-ka-web` | serveur FastAPI/Uvicorn (API + frontend + SSR) sur le port **8095** | | 128 | +| `lou-ka-web` | serveur FastAPI/Uvicorn (API + frontend + SSR) sur le port **8095** | continu | | ||
| 59 | −| `lou-ka-sync` | boucle de resynchronisation des connecteurs (`run.py watch`) | | 129 | +| `lou-ka-sync` | boucle de resynchronisation des connecteurs (`run.py watch 60`) | cycle de 60 min | | ||
| 60 | −| `lou-ka-ngrok` | tunnel ngrok vers **www.lou-ka.com** | | 130 | +| `lou-ka-ngrok` | tunnel ngrok vers **www.lou-ka.com** | continu | | ||
| 131 | + | ||||
| 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. | ||||
| 61 | 133 | ||||
| 62 | ## Structure du repo | 134 | ## Structure du repo | ||
| 63 | 135 | ||||
@@ -65,7 +137,7 @@ Processus PM2 sur le nœud : | |||||
| 65 | lou-ka/ | 137 | lou-ka/ | ||
| 66 | ├── run.py # point d'entrée CLI (sync / watch / serve / geocode / poi / quartier / record) | 138 | ├── run.py # point d'entrée CLI (sync / watch / serve / geocode / poi / quartier / record) | ||
| 67 | ├── louka/ # paquet backend : web, seo, db, ingest, normalize, textmine, auth, kascores… + connectors/ (212) | 139 | ├── louka/ # paquet backend : web, seo, db, ingest, normalize, textmine, auth, kascores… + connectors/ (212) | ||
| 68 | −├── frontend/ # React 18 + Vite + TypeScript (pages, composants, kamaps/) | 140 | +├── frontend/ # React 18 + Vite + TypeScript (pages, composants, kamaps/) + public/doc/ (guide) | ||
| 69 | ├── data/ # sources.json (registre) + bases SQLite de prod (gitignorées) | 141 | ├── data/ # sources.json (registre) + bases SQLite de prod (gitignorées) | ||
| 70 | ├── scripts/ # build recensement/contexte/environnement, screenshots, check-order | 142 | ├── scripts/ # build recensement/contexte/environnement, screenshots, check-order | ||
| 71 | ├── tests/ # pytest + fixtures HTTP rejouables hors-ligne | 143 | ├── tests/ # pytest + fixtures HTTP rejouables hors-ligne | ||
@@ -74,6 +146,12 @@ lou-ka/ | |||||
| 74 | └── docs/ # captures d'écran + docs connecteurs + ka-maps | 146 | └── docs/ # captures d'écran + docs connecteurs + ka-maps | ||
| 75 | ``` | 147 | ``` | ||
| 76 | 148 | ||||
| 149 | +## Documentation | ||||
| 150 | + | ||||
| 151 | +- **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. | ||||
| 152 | +- **Guide PDF** : [lou-ka-documentation.pdf](https://www.lou-ka.com/doc/lou-ka-documentation.pdf) — la même documentation, téléchargeable. | ||||
| 153 | +- Les captures du guide sont versionnées dans `frontend/public/doc/img/` (etape1 → etape4). | ||||
| 154 | + | ||||
| 77 | ## Développement (remote-first) | 155 | ## Développement (remote-first) | ||
| 78 | 156 | ||||
| 79 | **La source de vérité est le repo git sur le nœud M3U96b** (`~/apps/lou-ka`) — on n'édite jamais les copies laptop. Toute modification se fait sur le nœud via SSH : édition, build, `pm2 restart`, puis commit/push depuis le nœud. | 157 | **La source de vérité est le repo git sur le nœud M3U96b** (`~/apps/lou-ka`) — on n'édite jamais les copies laptop. Toute modification se fait sur le nœud via SSH : édition, build, `pm2 restart`, puis commit/push depuis le nœud. | ||
@@ -106,19 +184,26 @@ En développement frontend : `cd frontend && npm run dev` (Vite sur `:5173`, pro | |||||
| 106 | 184 | ||||
| 107 | ## Écosystème Groupe KA | 185 | ## Écosystème Groupe KA | ||
| 108 | 186 | ||||
| 109 | −- [groupe-ka.com](https://www.groupe-ka.com) — portail du groupe et compte unique KA ID | 187 | +| Plateforme | Vocation | | ||
| 110 | −- [lou-ka.com](https://www.lou-ka.com) — logements à louer *(ce repo)* | 188 | +|---|---| | ||
| 111 | −- [immo-ka.com](https://www.immo-ka.com) — propriétés à vendre | 189 | +| [groupe-ka.com](https://www.groupe-ka.com) | portail du groupe et compte unique KA ID | | ||
| 112 | −- [vrai-prix.com](https://www.vrai-prix.com) — estimation immobilière | 190 | +| [lou-ka.com](https://www.lou-ka.com) | logements à louer *(ce repo)* | | ||
| 113 | −- [auto-ka.com](https://www.auto-ka.com) — véhicules | 191 | +| [immo-ka.com](https://www.immo-ka.com) | propriétés à vendre | | ||
| 114 | −- [fabri-ka.com](https://www.fabri-ka.com) — produits québécois | 192 | +| [vrai-prix.com](https://www.vrai-prix.com) | estimation immobilière | | ||
| 115 | −- [food-ka.com](https://www.food-ka.com) — épicerie et alimentation | 193 | +| [auto-ka.com](https://www.auto-ka.com) | véhicules | | ||
| 116 | −- [resto-ka.com](https://www.resto-ka.com) — restaurants | 194 | +| [fabri-ka.com](https://www.fabri-ka.com) | produits québécois | | ||
| 117 | −- [sorti-ka.com](https://www.sorti-ka.com) — sorties et événements | 195 | +| [food-ka.com](https://www.food-ka.com) | épicerie et alimentation | | ||
| 118 | −- [job-ka.com](https://www.job-ka.com) — emplois | 196 | +| [resto-ka.com](https://www.resto-ka.com) | restaurants | | ||
| 119 | −- [crea-ka.com](https://www.crea-ka.com) — créateurs de contenu | 197 | +| [sorti-ka.com](https://www.sorti-ka.com) | sorties et événements | | ||
| 120 | −- [trouve-ka.com](https://www.trouve-ka.com) — petites annonces | 198 | +| [job-ka.com](https://www.job-ka.com) | emplois | | ||
| 121 | −- [api-ka.com](https://www.api-ka.com) — API de données | 199 | +| [crea-ka.com](https://www.crea-ka.com) | créateurs de contenu | | ||
| 200 | +| [trouve-ka.com](https://www.trouve-ka.com) | petites annonces | | ||||
| 201 | +| [api-ka.com](https://www.api-ka.com) | API de données | | ||||
| 202 | + | ||||
| 203 | +## Contact | ||||
| 204 | + | ||||
| 205 | +**Simon-Pierre Boucher** — fondateur, Groupe KA | ||||
| 206 | +📧 [contact@spboucher.ai](mailto:contact@spboucher.ai) | ||||
| 122 | 207 | ||||
| 123 | --- | 208 | --- | ||
| 124 | 209 | ||||
| 125 | 210 | ||||