docs: refonte du README (pastilles + captures d écran à jour)
3 changed files +90 −249
modified
README.md
+90 −249
@@ -1,291 +1,132 @@ | |||||
| 1 | −<div align="center"> | ||||
| 2 | − | ||||
| 3 | # Vrai-Prix | 1 | # Vrai-Prix | ||
| 4 | 2 | ||||
| 5 | −**La vraie valeur de votre propriété, sans boîte noire.** | 3 | +**La vraie valeur de votre propriété, sans boîte noire — estimation immobilière transparente pour tout le Québec.** | ||
| 6 | − | ||||
| 7 | −Moteur d'évaluation immobilière **transparent** pour le Québec — **3 747 008 propriétés**, | ||||
| 8 | −**745 119 ventes réelles (2021-2026)**, chaque calcul montré en entier. | ||||
| 9 | 4 | ||||
| 10 | − | 5 | +[](https://www.vrai-prix.com) | ||
| 11 | − | 6 | + | ||
| 12 | − | 7 | + | ||
| 13 | − | 8 | + | ||
| 14 | − | ||||
| 15 | − | ||||
| 16 | − | ||||
| 17 | − | ||||
| 18 |  | 9 |  | ||
| 19 |  | 10 |  | ||
| 20 | − | ||||
| 21 |  | 11 |  | ||
| 22 | − | 12 | + | ||
| 23 | − | 13 | + | ||
| 24 | −**En production : [www.vrai-prix.com](https://www.vrai-prix.com)** | ||||
| 25 | − | ||||
| 26 | −</div> | ||||
| 27 | − | ||||
| 28 | − | ||||
| 29 | − | ||||
| 30 | −--- | ||||
| 31 | − | ||||
| 32 | −## Sommaire | ||||
| 33 | 14 | ||||
| 34 | −- [Ce que fait Vrai-Prix](#ce-que-fait-vrai-prix) | 15 | +Vrai-Prix estime la valeur marchande de **n'importe quelle propriété du Québec** — unifamiliale, plex, condo, chalet, terrain — et montre *pourquoi* : chaque comparable, chaque ajustement en dollars, la pondération du modèle, la fourchette (P10–P90) et l'indice de confiance (A–D). Le différenciateur est la **transparence totale** : pas de score magique, pas de boîte noire. La méthodologie complète (normes **IAAO**) est publiée intégralement sur le site. | ||
| 35 | −- [Fonctionnalités](#fonctionnalités) | ||||
| 36 | −- [Visite guidée](#visite-guidée) | ||||
| 37 | −- [Les chiffres qui comptent](#les-chiffres-qui-comptent) | ||||
| 38 | −- [Architecture](#architecture) | ||||
| 39 | −- [Le moteur d'estimation](#le-moteur-destimation-srclibenginets) | ||||
| 40 | −- [Ka — l'agent IA](#ka--lagent-ia) | ||||
| 41 | −- [SEO programmatique](#seo-programmatique--376-m-durls-indexables) | ||||
| 42 | −- [Structure du projet](#structure-du-projet) | ||||
| 43 | −- [Endpoints](#endpoints) | ||||
| 44 | −- [Démarrage local](#démarrage-local) | ||||
| 45 | −- [Déploiement](#déploiement) | ||||
| 46 | −- [Développement remote-first](#développement-remote-first) | ||||
| 47 | −- [Design](#design) | ||||
| 48 | −- [Auteur](#auteur) | ||||
| 49 | 16 | ||||
| 50 | −## Ce que fait Vrai-Prix | 17 | +Sous le capot : les **6 millésimes (2021-2026)** des rôles d'évaluation foncière géoréférencés du Québec (**MAMH**, données ouvertes) — **3 747 008 propriétés**, soit **22 150 285 observations** — fusionnés spatialement avec **745 119 transactions réelles** (99,88 % d'appariement, distance médiane 0,6 m), alimentant un **modèle hédonique LightGBM** (MdAPE 11,0 %, ratio médian 0,995 en holdout) et un **moteur de comparables ajustés**. Pour qui ? Propriétaires, acheteurs, courtiers et curieux qui veulent une estimation honnête et vérifiable, gratuite, sur les **1 097 municipalités** de la province. | ||
| 51 | 18 | ||||
| 52 | −Vrai-Prix estime la valeur marchande de **n'importe quelle propriété du Québec** (unifamiliale, plex, condo, chalet, terrain) et montre *pourquoi* — **chaque comparable, chaque ajustement en dollars**, la pondération du modèle, la fourchette et l'indice de confiance. Le différenciateur est la **transparence totale** : pas de score magique, **pas de boîte noire**. La méthodologie complète (normes **IAAO**) est publiée intégralement sur le site. | 19 | +## Captures d'écran | ||
| 53 | 20 | ||||
| 54 | −Sous le capot : les **6 millésimes (2021-2026)** des rôles d'évaluation foncière géoréférencés du Québec (**MAMH**, données ouvertes) — soit **22 150 285 observations** — fusionnés spatialement avec **745 119 transactions réelles** (**99,88 %** d'appariement, distance médiane **0,6 m**), alimentant un **modèle hédonique LightGBM** et un **moteur de comparables ajustés**. | 21 | +<p align="center"> | ||
| 22 | + <img src="docs/screenshots/vrai-prix-desktop.png" width="640" alt="Accueil — desktop"> | ||||
| 23 | + <img src="docs/screenshots/vrai-prix-mobile.png" width="200" alt="Accueil — mobile"> | ||||
| 24 | +</p> | ||||
| 55 | 25 | ||||
| 56 | ## Fonctionnalités | 26 | ## Fonctionnalités | ||
| 57 | 27 | ||||
| 58 | −| Fonctionnalité | Description | | 28 | +- **Estimation par adresse** — recherche plein-texte (SQLite FTS5) parmi 3 747 008 unités d'évaluation, tolérante aux fautes ; **plan B sans adresse** : estimation manuelle par municipalité + caractéristiques. | ||
| 59 | −|---|---| | 29 | +- **Estimation hybride** — 65 % modèle hédonique LightGBM + 35 % comparables ajustés (marché, superficie, âge), fourchette P10–P90 par régression quantile, indice de confiance A–D obligatoire. | ||
| 60 | −| 🔎 **Estimation par adresse** | Recherche plein-texte (**FTS5**) parmi **3 747 008 unités d'évaluation**, tolérante aux fautes | | 30 | +- **Portrait de la propriété** — façade SVG dessinée par les données du registre, terrain à l'échelle, composition de la valeur ; historique 2021→2026 (six millésimes, badges YoY). | ||
| 61 | −| 🧮 **Plan B sans adresse** | **Estimation manuelle** (municipalité + caractéristiques) quand la propriété n'est pas au registre | | 31 | +- **Vrai-Prix Maps** — recherche par carte 3D (Mapbox GL via le framework partagé `@groupe-ka/ka-maps`), grappes de valeurs estimées pilotées par le viewport ; plan des comparables « arpenteur » en SVG pur. | ||
| 62 | −| 💰 **Estimation hybride** | **65 % modèle hédonique + 35 % comparables ajustés** | | 32 | +- **Ka · agent IA** — agent conversationnel (Claude, SDK Anthropic, streaming SSE) branché sur **12 outils serveur** : évaluation, comparables, stats, dossier d'expert, parc immobilier. | ||
| 63 | −| 📊 **Fourchette + confiance** | **P10–P90** par régression quantile, indice **A–D** obligatoire | | 33 | +- **Rapports PDF 100 % vectoriels** (pdfkit) — standard (3 p.), professionnel bancaire (6 p.), parc consolidé, statistique provincial. | ||
| 64 | −| 🏠 Portrait de la propriété | Façade SVG dessinée par les données du registre, terrain à l'échelle, composition de la valeur | | 34 | +- **Parc immobilier** — évaluation multi-adresses agrégée (jusqu'à 40 propriétés). | ||
| 65 | −| 🗺️ **Vrai-Prix Maps** | Recherche par **carte 3D** (Mapbox GL via le framework partagé **Ka Maps**) — grappes de valeurs estimées pilotées par le viewport | | 35 | +- **Statistiques provinciales** — valeur totale du parc (2,01 billions $), palmarès des 200 municipalités, tableau de bord `/stats` + rapports PDF v3. | ||
| 66 | −| 📐 Plan des comparables | Carte « plan d'arpenteur » maison (SVG pur, zéro tuile) — azimut et distance réels | | 36 | +- **SEO programmatique — 3,76 M d'URLs indexables** : 1 097 pages municipalités + ~5 900 pages municipalité × type + 3,75 M fiches d'estimation SSR avec métadonnées uniques, JSON-LD, sitemaps générés à la volée. | ||
| 67 | −| 📈 Historique 2021→2026 | **Six millésimes** d'estimations par propriété, badges YoY | | 37 | +- **KA ID** — connexion unique du Groupe KA (SSO signé via le hub groupe-ka.com, sans base d'utilisateurs) + favoris « Mon univers Ka ». | ||
| 68 | −| 🤖 **Ka · agent IA** | Agent conversationnel (**Claude**) branché sur **12 outils serveur** : évaluation, comparables, stats, dossier d'expert | | 38 | +- **Bilingue FR/EN**, méthodologie publique (7 sections, IAAO), conformité Loi 25, app compagnon iOS SwiftUI (dépôt séparé). | ||
| 69 | −| 🏢 Parc immobilier | Évaluation multi-adresses agrégée (jusqu'à **40 propriétés**) + rapport consolidé | | ||||
| 70 | −| 📄 Rapports PDF | Standard (3 p.), professionnel bancaire (6 p.), parc (n+1 p.), statistique provincial — **100 % vectoriels** | | ||||
| 71 | −| 📉 **Statistiques** | Valeur totale de la province (**2,01 billions $**), palmarès des **200** municipalités | | ||||
| 72 | −| 🏙️ Pages municipalités | **1 097** pages programmatiques (médiane, croissance, médianes par type) + **~5 900** pages municipalité × type | | ||||
| 73 | −| 🔑 KA ID | Connexion unique du **Groupe KA** (SSO signé via le hub groupe-ka.com, session sans base d'utilisateurs) | | ||||
| 74 | −| 🌐 Bilingue | **FR** (défaut) / **EN**, bascule instantanée côté client | | ||||
| 75 | −| 📱 App iOS | Compagnon natif **SwiftUI** (onglet carte MapKit) — dépôt séparé | | ||||
| 76 | −| ⚖️ **Méthodologie transparente** | Loi 25, sélecteur de témoins, méthodologie publique intégrale (7 sections, normes **IAAO**) | | ||||
| 77 | − | ||||
| 78 | −## Visite guidée | ||||
| 79 | − | ||||
| 80 | −| | | | ||||
| 81 | −|---|---| | ||||
| 82 | −| **Fiche d'estimation** — valeur, fourchette honnête, écart vs rôle, indice de confiance | **Portrait de la propriété** — bâtiment, terrain à l'échelle et valeurs dessinés par les données | | ||||
| 83 | −| <img src="docs/screenshots/fiche-estimation.png" alt="Fiche d'estimation" width="460"> | <img src="docs/screenshots/fiche-portrait.png" alt="Portrait de la propriété" width="460"> | | ||||
| 84 | −| **Vrai-Prix Maps** — votre quartier, estimé (grappes de valeurs 2026) | **Ka · agent IA** — évaluation en conversant, calcul montré | | ||||
| 85 | −| <img src="docs/screenshots/carte.png" alt="Recherche par carte" width="460"> | <img src="docs/screenshots/ka-agent.png" alt="Agent IA Ka" width="460"> | | ||||
| 86 | −| **Statistiques provinciales** — 2,01 billions $, palmarès des municipalités | **Pages municipalités** — 1 097 pages programmatiques indexables | | ||||
| 87 | −| <img src="docs/screenshots/stats.png" alt="Statistiques provinciales" width="460"> | <img src="docs/screenshots/municipalite.png" alt="Page municipalité Gatineau" width="460"> | | ||||
| 88 | −| **Méthodologie publique** — 7 sections, normes IAAO, rien de caché | **Mobile** — même expérience, menu plein écran pur CSS | | ||||
| 89 | −| <img src="docs/screenshots/methodologie.png" alt="Méthodologie" width="460"> | <img src="docs/screenshots/accueil-mobile.png" alt="Accueil mobile" width="230"> <img src="docs/screenshots/fiche-mobile.png" alt="Fiche mobile" width="230"> | | ||||
| 90 | − | ||||
| 91 | −## Les chiffres qui comptent | ||||
| 92 | − | ||||
| 93 | −Validation sur **102 943 ventes jamais vues** du modèle (holdout aléatoire) et **test temporel strict** (entraîné sans 2026, testé sur **68 364 ventes de 2026**), selon la **norme IAAO sur études de ratios** : | ||||
| 94 | − | ||||
| 95 | −| Métrique | Holdout | Test temporel 2026 | Cible IAAO | | ||||
| 96 | −|---|---|---|---| | ||||
| 97 | −| Erreur médiane (MdAPE) | **11,0 %** | 14,0 % | — | | ||||
| 98 | −| À ±20 % du prix réel | **72,1 %** | 66,7 % | — | | ||||
| 99 | −| Ratio médian | **0,995** | 0,961 | 0,90–1,10 ✅ | | ||||
| 100 | −| COD | 22,7 (condos : **11,9** ✅) | 23,7 | ≤ 15–20 | | ||||
| 101 | −| PRD | 1,092 | 1,075 | 0,98–1,03 | | ||||
| 102 | −| R² (log) | **0,789** | 0,743 | — | | ||||
| 103 | 39 | ||||
| 104 | ## Architecture | 40 | ## Architecture | ||
| 105 | 41 | ||||
| 106 | ``` | 42 | ``` | ||
| 107 | −┌─ Données ouvertes MAMH ──────────────────────────────────────────┐ | 43 | +Rôles d'évaluation MAMH 2021-2026 (6 millésimes × ~3,7 M unités) | ||
| 108 | −│ Rôles d'évaluation foncière géoréférencés 2021-2026 │ | 44 | + │ fusion spatiale XY (EPSG:32198) — kNN k=25 ≤200 m | ||
| 109 | −│ 6 millésimes × ~3,7 M unités = 22 150 285 observations │ | 45 | + ▼ | ||
| 110 | −└──────────────┬───────────────────────────────────────────────────┘ | 46 | +745 119 transactions enrichies ──▶ modèle hédonique LightGBM (log-prix, | ||
| 111 | − │ fusion spatiale XY (EPSG:32198) | 47 | + 18 variables + quantiles P10/P90) | ||
| 112 | − │ kNN k=25 ≤200 m + jointure par valeur ≤500 m | 48 | + ▼ | ||
| 113 | − │ → 99,88 % appariées, distance médiane 0,6 m | 49 | +Application Next.js 16 (App Router) — SQLite better-sqlite3 (units + FTS5 | ||
| 114 | −┌──────────────▼───────────────┐ ┌──────────────────────────────┐ | 50 | ++ transactions + indice de marché) · moteur de comparables (src/lib/engine.ts) | ||
| 115 | −│ 745 119 transactions │ │ Modèle hédonique LightGBM │ | 51 | +· Ka Maps (Mapbox GL) · agent Ka (Claude + 12 outils) · rapports pdfkit | ||
| 116 | −│ enrichies du rôle ├──▶│ log(prix), 18 variables │ | 52 | +· SSO KA ID · SEO programmatique | ||
| 117 | −└──────────────────────────────┘ │ + quantiles P10/P90 │ | ||||
| 118 | − │ → 22 M d'estimations │ | ||||
| 119 | − └──────────────┬───────────────┘ | ||||
| 120 | −┌─ Application Next.js 16 ─────────────────────────▼───────────────┐ | ||||
| 121 | −│ SQLite (units + FTS5 + transactions + indice de marché) │ | ||||
| 122 | −│ Moteur comparables (ajust. marché/superficie/âge, médiane │ | ||||
| 123 | −│ pondérée) · Ka Maps (Mapbox GL) · agent Ka (Claude + 12 outils) │ | ||||
| 124 | −│ RadarMap SVG · MetricViz · rapports pdfkit · SSO KA ID │ | ||||
| 125 | −│ SEO programmatique (1 097 municipalités · sitemaps 3,76 M URLs) │ | ||||
| 126 | −└──────────────────────────────────────────────────────────────────┘ | ||||
| 127 | ``` | 53 | ``` | ||
| 128 | 54 | ||||
| 129 | −### Stack | 55 | +- **Frontend / API** : Next.js 16, TypeScript strict, Tailwind CSS 4 — tout est servi par une seule app (pages SSR + routes `/api/*` : `search`, `estimate`, `nearby`, `ka`, `portfolio`, `report*`, `stats`, `auth`). | ||
| 130 | − | 56 | +- **Base de données** : SQLite (`data/vraiprix.db`, ~1,5 Go, non versionnée) — 3,75 M unités, FTS5, index spatiaux, mode WAL. | ||
| 131 | −- **Frontend / API** : **Next.js 16** (App Router), **TypeScript strict**, **Tailwind CSS 4** | 57 | +- **Modèle** : pipeline externe LightGBM / scikit-learn (réentraînement : `scripts/hedonic-retrain.py`), estimations pré-calculées injectées dans la base. | ||
| 132 | −- **Base** : **SQLite** (better-sqlite3) — **3,75 M unités**, **FTS5**, index spatiaux *(non incluse dans ce dépôt)* | 58 | +- **Tests** : Vitest (moteur d'estimation) + Playwright (captures : `scripts/screenshots.mjs`). | ||
| 133 | −- **Cartes** : **`@groupe-ka/ka-maps`** (framework carto partagé du Groupe KA, moteur **Mapbox GL**, style Standard 3D) | 59 | +- **Processus PM2** : | ||
| 134 | −- **Agent IA** : **SDK Anthropic** (Claude Haiku 4.5, streaming SSE, boucle agentique manuelle, prompt caching) | 60 | + - **`vrai-prix`** — l'app Next.js (`next start -H 0.0.0.0 -p 8090`) ; | ||
| 135 | −- **Rapports** : **pdfkit**, 100 % vectoriels, polices embarquées (Space Grotesk / Inter / JetBrains Mono) | 61 | + - **`vrai-prix-ngrok`** — tunnel ngrok vers www.vrai-prix.com. | ||
| 136 | −- **Modèle** (pipeline externe) : **LightGBM**, scikit-learn, pandas, pyogrio/GDAL | ||||
| 137 | −- **Tests** : **Vitest** (moteur d'estimation) + **Playwright** (mobile, captures d'écran) | ||||
| 138 | −- **Prod** : **PM2** + **ngrok** sur le nœud **M3U96a** du cluster MacLustr | ||||
| 139 | − | ||||
| 140 | −## Le moteur d'estimation (`src/lib/engine.ts`) | ||||
| 141 | − | ||||
| 142 | −1. **Comparables** : ventes candidates dans un rayon adaptatif (**2,2 → 28 km**), filtrées par type et superficie (±20 → ±40 %) ; | ||||
| 143 | −2. **Ajustements affichés en dollars** : conditions de marché (indice mensuel $/m² lissé 3 mois), superficie (50 % du $/m² du comparable, plafonné ±25 %), âge (0,5 %/an, plafonné ±10 %) ; | ||||
| 144 | −3. **Pondération gaussienne** : distance (σ 1 500 m), récence (σ 24 mois), similarité de superficie (σ 25 %) ; | ||||
| 145 | −4. **Fusion** : **65 % modèle hédonique** pré-calculé + **35 % médiane pondérée des comparables** ; | ||||
| 146 | −5. **Confiance** : nombre de comparables, dispersion, largeur de fourchette → **A/B/C/D**. | ||||
| 147 | − | ||||
| 148 | −Chaque fiche montre le calcul **en entier** : les comparables retenus, chaque ajustement, les poids, la réconciliation. Le rapport PDF « professionnel » reprend la grille d'ajustement au format des évaluateurs (avec les encadrés « ceci n'est pas un rapport OEAQ »). | ||||
| 149 | − | ||||
| 150 | −## Ka — l'agent IA | ||||
| 151 | − | ||||
| 152 | −Page [`/ka`](https://www.vrai-prix.com/ka) : un agent conversationnel branché **en direct** sur le registre et le moteur. Boucle agentique manuelle (**12 tours max**) avec **12 outils serveur** : `chercher_propriete` (FTS avec relaxation progressive), `evaluer_propriete`, `dossier_complet` (évaluation + marché + tendance + comparables + synthèse en un appel), `comparables_detailles`, `indice_marche`, `stats_municipalite`, `stats_provinciales`, `evaluer_parc`, `comparer_proprietes`, `estimation_manuelle`, `chercher_proprietes_secteur`, `liens_rapports` (réfs persistantes anti-hallucination pour les PDF). **Streaming SSE**, tableaux HTML dans le fil, clarification quand l'adresse est ambiguë. | ||||
| 153 | − | ||||
| 154 | −## SEO programmatique — 3,76 M d'URLs indexables | ||||
| 155 | − | ||||
| 156 | −Tout le contenu est servi **en HTML complet dès la première requête** (SSR), avec un maillage interne crawlable : | ||||
| 157 | − | ||||
| 158 | −- **`/municipalites`** → index A-Z des **1 097 municipalités** ; | ||||
| 159 | −- **`/municipalite/[slug]`** (**1 097 pages**) → médiane 2026, valeur totale, croissance 2021→2026, médianes par type, 24 fiches liées, municipalités voisines ; | ||||
| 160 | −- **`/municipalite/[slug]/[type]`** (**~5 900 pages**) → `maison`, `plex`, `chalet`, `condo`, `terrain`, `maison-mobile`, `autre` ; | ||||
| 161 | −- **`/estimation/[id]`** (**3,75 M fiches**) → title et meta description **uniques par fiche** (adresse + estimation), canonical, JSON-LD `SingleFamilyResidence`/`Residence`/`Place` + `BreadcrumbList` ; | ||||
| 162 | −- **Sitemaps** : `/sitemap-index.xml` → `/sitemap.xml` (7 043 pages) + `/estimation/sitemap/0-83.xml` (45 000 fiches chacun, générés à la volée depuis SQLite par plages de rowid) ; | ||||
| 163 | −- JSON-LD `Organization` + `WebSite` global, `robots.txt` propre, `noindex` sur les pages privées/paramétriques. | ||||
| 164 | − | ||||
| 165 | −Les agrégats par municipalité (`src/lib/municipalites.ts`) sont calculés en SQL et mis en cache mémoire par processus — première visite ~1 s (Montréal), ensuite ~30 ms. | ||||
| 166 | 62 | ||||
| 167 | −## Structure du projet | 63 | +## Structure du repo | ||
| 168 | 64 | ||||
| 169 | −``` | 65 | +| Répertoire | Rôle | | ||
| 170 | −src/ | 66 | +|---|---| | ||
| 171 | −├─ app/ | 67 | +| `src/app/` | pages App Router (accueil, `estimation/[id]`, `municipalite/[slug]/[type]`, `carte`, `ka`, `parc`, `stats`, `favoris`, sitemaps/robots) + routes `/api/*` | | ||
| 172 | −│ ├─ page.tsx / HomeClient.tsx # accueil (recherche + estimation manuelle) | 68 | +| `src/components/` | SearchBox, ResultView, MetricViz, RadarMap, KaCarte, KaChat, StatsView… | | ||
| 173 | −│ ├─ estimation/[id]/ # fiche (SSR + generateMetadata + JSON-LD) | 69 | +| `src/lib/` | moteur de comparables (`engine.ts`), accès DB, agrégats municipalités, agent Ka, SSO KA ID, générateurs PDF | | ||
| 174 | −│ ├─ estimation/manuelle/ # estimation sans adresse (noindex) | 70 | +| `data/` | base SQLite `vraiprix.db` (non versionnée) | | ||
| 175 | −│ ├─ municipalites/ # index A-Z (programmatique) | 71 | +| `scripts/` | réentraînement hédonique, build des stats, ingestion, captures Playwright | | ||
| 176 | −│ ├─ municipalite/[slug]/[type]/ # 1 097 + ~5 900 pages programmatiques | 72 | +| `docs/` | pipeline de données, notes Ka Maps, captures d'écran | | ||
| 177 | −│ ├─ carte/ # Vrai-Prix Maps (Ka Maps / Mapbox GL) | 73 | +| `public/` | assets statiques (favicons, OG, polices) | | ||
| 178 | −│ ├─ ka/ # agent IA (streaming SSE) | 74 | +| `ios/` | ressources de l'app compagnon iOS (SwiftUI) | | ||
| 179 | −│ ├─ parc/ # parc immobilier multi-adresses | 75 | +| `assets/` | matériel graphique du projet | | ||
| 180 | −│ ├─ stats/ # statistiques provinciales | ||||
| 181 | −│ ├─ compte/ # carte de membre Groupe KA (SSO) | ||||
| 182 | −│ ├─ methodologie|conditions|confidentialite/ | ||||
| 183 | −│ ├─ sitemap.ts · estimation/sitemap.ts · sitemap-index.xml/ · robots.ts | ||||
| 184 | −│ └─ api/ # endpoints (voir tableau) | ||||
| 185 | −├─ components/ # SearchBox, ResultView, MetricViz, RadarMap, | ||||
| 186 | −│ # KaCarte, KaChat, StatsView, LangContext… | ||||
| 187 | −├─ lib/ | ||||
| 188 | −│ ├─ engine.ts # moteur comparables (testé Vitest) | ||||
| 189 | −│ ├─ estimator.ts # service DB ↔ moteur | ||||
| 190 | −│ ├─ db.ts # SQLite (better-sqlite3, WAL) | ||||
| 191 | −│ ├─ municipalites.ts # agrégats programmatiques (cache mémoire) | ||||
| 192 | −│ ├─ seo.ts # slugs, libellés, constantes SEO | ||||
| 193 | −│ ├─ ka/ # agent IA (outils serveur, prompt) | ||||
| 194 | −│ ├─ ka-auth.ts · hub-profile.ts # SSO KA ID (JWT HS256, node:crypto pur) | ||||
| 195 | −│ └─ report*.ts # 4 générateurs PDF (pdfkit) | ||||
| 196 | −└─ data/stats.json # agrégats provinciaux précalculés | ||||
| 197 | −``` | ||||
| 198 | 76 | ||||
| 199 | −## Endpoints | 77 | +## Développement (remote-first) | ||
| 200 | 78 | ||||
| 201 | −| Route | Description | | 79 | +⚠️ **La source de vérité est le repo git sur le nœud M3U96a** (`~/apps/vrai-prix`) — on n'édite **jamais** les copies laptop. Toute modification se fait sur le nœud via SSH : édition, build, redémarrage, puis commit + push **depuis le nœud**. | ||
| 202 | −|---|---| | ||||
| 203 | −| `GET /api/search?q=` | Autocomplétion d'adresses (FTS5) | | ||||
| 204 | −| `GET /api/estimate?id=` | Estimation complète d'une unité | | ||||
| 205 | −| `POST /api/estimate` | Estimation manuelle (municipalité + caractéristiques) | | ||||
| 206 | −| `GET /api/nearby?lat&lng&halfLat&halfLng` | Unités dans une boîte englobante (carte) | | ||||
| 207 | −| `POST /api/ka` | Agent IA (streaming SSE, boucle d'outils) | | ||||
| 208 | −| `POST /api/portfolio` | Agrégation d'un parc (jusqu'à 40 ids) | | ||||
| 209 | −| `GET /api/report?id=` | Rapport PDF standard (3 pages) | | ||||
| 210 | −| `GET /api/report/pro?id=` | Rapport détaillé format professionnel (6 pages) | | ||||
| 211 | −| `GET /api/report/portfolio?ids=` | Rapport de parc consolidé | | ||||
| 212 | −| `GET /api/report/stats` | Rapport statistique provincial | | ||||
| 213 | −| `GET /api/stats` · `/api/stats/dashboard` | Agrégats provinciaux (métriques live du hub Groupe KA) | | ||||
| 214 | −| `GET /api/auth/ka/login` · `/callback` | SSO KA ID (hub groupe-ka.com) | | ||||
| 215 | −| `GET /api/auth/me` · `POST /api/auth/logout` | Session (cookie signé, sans table users) | | ||||
| 216 | 80 | ||||
| 217 | −## Démarrage local | 81 | +- Remote **`origin` = spbgit** (git perso, https://git.spboucher.ai) — sur M3U96a, l'origin est le chemin local **`/Users/simon-pierreboucher/srv/git/vrai-prix.git`** (bare repo) ; | ||
| 82 | +- remote secondaire `github` → github.com/spboucher-ai/vrai-prix. | ||||
| 218 | 83 | ||||
| 219 | ```bash | 84 | ```bash | ||
| 220 | −npm install | 85 | +ssh M3U96a | ||
| 221 | −# placer la base de données dans data/vraiprix.db (non versionnée) | 86 | +cd ~/apps/vrai-prix | ||
| 222 | −npm run dev # développement | 87 | +npm install # au besoin | ||
| 223 | −npm run test # tests du moteur (Vitest) | 88 | +npm run test # Vitest — moteur d'estimation | ||
| 224 | −npm run build && npm run start | 89 | +npm run dev # développement | ||
| 90 | +npm run build # build de production | ||||
| 91 | +pm2 restart vrai-prix # après changement | ||||
| 92 | +git add <fichiers> && git commit -m "…" && git push origin main | ||||
| 225 | ``` | 93 | ``` | ||
| 226 | 94 | ||||
| 227 | −### Variables d'environnement | 95 | +Variables d'environnement clés : `VRAIPRIX_DB`, `NEXT_PUBLIC_SITE_URL`, `ANTHROPIC_API_KEY` (agent Ka), `NEXT_PUBLIC_MAPBOX_TOKEN` (carte), `KA_SSO_SECRET`/`KA_AUTH_SECRET`/`KA_HUB_URL`/`KA_BASE_URL` (SSO). | ||
| 228 | − | ||||
| 229 | −| Variable | Rôle | | ||||
| 230 | −|---|---| | ||||
| 231 | −| `VRAIPRIX_DB` | Chemin de la base SQLite (défaut : `data/vraiprix.db`) | | ||||
| 232 | −| `NEXT_PUBLIC_SITE_URL` | URL canonique (défaut : `https://www.vrai-prix.com`) | | ||||
| 233 | −| `ANTHROPIC_API_KEY` | Agent IA Ka (page `/ka`) | | ||||
| 234 | −| `NEXT_PUBLIC_MAPBOX_TOKEN` | Vrai-Prix Maps (page `/carte`) | | ||||
| 235 | −| `KA_SSO_SECRET` · `KA_AUTH_SECRET` · `KA_HUB_URL` · `KA_BASE_URL` | SSO KA ID | | ||||
| 236 | − | ||||
| 237 | −> **Note données** : la base SQLite (1,5 Go) et les pipelines d'entraînement ne sont pas versionnés. Données sources : [rôles d'évaluation foncière du Québec](https://www.donneesquebec.ca/recherche/dataset/roles-d-evaluation-fonciere-du-quebec) (MAMH, licence ouverte). Les renseignements des propriétaires sont caviardés à la source. | ||||
| 238 | − | ||||
| 239 | −> **Captures d'écran** : `node scripts/screenshots.mjs` les régénère depuis la prod (Playwright). | ||||
| 240 | 96 | ||||
| 241 | ## Déploiement | 97 | ## Déploiement | ||
| 242 | 98 | ||||
| 243 | −L'app tourne en production sur le cluster **MacLustr** : | ||||
| 244 | − | ||||
| 245 | | | | | 99 | | | | | ||
| 246 | |---|---| | 100 | |---|---| | ||
| 247 | −| **Nœud** | **M3U96a** (Mac Studio M3 Ultra, 32 cœurs / 96 Go) — `~/apps/vrai-prix` | | 101 | +| **Nœud** | **M3U96a** (Mac Studio M3 Ultra, cluster MacLustr) — `~/apps/vrai-prix` | | ||
| 248 | −| **Port** | **8090** (`next start -H 0.0.0.0 -p 8090`) | | 102 | +| **Port** | **8090** | | ||
| 249 | −| **Domaine** | **[www.vrai-prix.com](https://www.vrai-prix.com)** (tunnel ngrok) | | 103 | +| **Processus PM2** | `vrai-prix` (Next.js) + `vrai-prix-ngrok` (tunnel) | | ||
| 250 | −| **Processus PM2** | **`vrai-prix`** (app Next.js) + **`vrai-prix-ngrok`** (tunnel) | | 104 | +| **Domaine** | [www.vrai-prix.com](https://www.vrai-prix.com) via tunnel ngrok | | ||
| 251 | 105 | ||||
| 252 | ```bash | 106 | ```bash | ||
| 253 | # sur M3U96a, après un changement : | 107 | # sur M3U96a, après un changement : | ||
| 254 | −cd ~/apps/vrai-prix | 108 | +cd ~/apps/vrai-prix && npm run build && pm2 restart vrai-prix | ||
| 255 | −npm run build | 109 | +pm2 logs vrai-prix --lines 30 | ||
| 256 | −pm2 restart vrai-prix | ||||
| 257 | −pm2 logs vrai-prix --lines 30 # vérifier le démarrage | ||||
| 258 | ``` | 110 | ``` | ||
| 259 | 111 | ||||
| 260 | −## Développement remote-first | 112 | +## Écosystème Groupe KA | ||
| 261 | − | 113 | + | ||
| 262 | −⚠️ **La source de vérité est le repo git sur le nœud M3U96a** (`~/apps/vrai-prix`), **pas** une copie laptop. Toute modification se fait sur le nœud via SSH : édition, `npm run build`, `pm2 restart vrai-prix`, puis commit + push **sur le nœud**. | 114 | +- [groupe-ka.com](https://www.groupe-ka.com) — portail | ||
| 263 | − | 115 | +- [lou-ka.com](https://www.lou-ka.com) — logements à louer | ||
| 264 | −- Remote **`origin` = spbgit** (git perso, git.spboucher.ai) — sur **M3U96a** le remote pointe directement sur le chemin local **`/Users/simon-pierreboucher/srv/git/vrai-prix.git`** (bare repo) ; | 116 | +- [immo-ka.com](https://www.immo-ka.com) — propriétés à vendre | ||
| 265 | −- Remote secondaire `github` → `github.com/spboucher-ai/vrai-prix` ; | 117 | +- [vrai-prix.com](https://www.vrai-prix.com) — estimation immobilière | ||
| 266 | −- Référence complète du workflow : `~/Desktop/cluster-skill/KA-REMOTE-DEV.md`. | 118 | +- [auto-ka.com](https://www.auto-ka.com) — véhicules | ||
| 267 | − | 119 | +- [fabri-ka.com](https://www.fabri-ka.com) — produits québécois | ||
| 268 | −```bash | 120 | +- [food-ka.com](https://www.food-ka.com) — épicerie / alimentation | ||
| 269 | −ssh M3U96a | 121 | +- [resto-ka.com](https://www.resto-ka.com) — restaurants | ||
| 270 | −cd ~/apps/vrai-prix | 122 | +- [sorti-ka.com](https://www.sorti-ka.com) — sorties et événements | ||
| 271 | −# … modifier, builder, redémarrer … | 123 | +- [job-ka.com](https://www.job-ka.com) — emplois | ||
| 272 | −git add <fichiers> && git commit -m "…" && git push origin main | 124 | +- [crea-ka.com](https://www.crea-ka.com) — créateurs | ||
| 273 | −``` | 125 | +- [trouve-ka.com](https://www.trouve-ka.com) — petites annonces | ||
| 274 | − | 126 | +- [api-ka.com](https://www.api-ka.com) — API de données | ||
| 275 | −## Design | ||||
| 276 | − | ||||
| 277 | −Identité « éditorial sharp » : papier grainé `#f5f3ee`, encre `#141814`, **accent rouge vif `#ff5148`**, bordeaux `#9e2a25` — bordures encre 1,5 px, ombres décalées, display uppercase (Space Grotesk), micro-étiquettes mono (JetBrains Mono), ticker marquee, visualisations SVG data-driven (façade du bâtiment, terrain à l'échelle, jauge de confiance, sparklines) — **zéro image bitmap dans l'app**. | ||||
| 278 | − | ||||
| 279 | −## Auteur | ||||
| 280 | − | ||||
| 281 | −**Simon-Pierre Boucher** — [contact@spboucher.ai](mailto:contact@spboucher.ai) | ||||
| 282 | − | ||||
| 283 | −*Estimations statistiques à titre indicatif — ne remplacent pas une évaluation par un évaluateur agréé (OEAQ). Voir [conditions](https://www.vrai-prix.com/conditions) et [méthodologie complète](https://www.vrai-prix.com/methodologie).* | ||||
| 284 | 127 | ||||
| 285 | --- | 128 | --- | ||
| 286 | 129 | ||||
| 287 | −<div align="center"> | 130 | +© Groupe KA — Simon-Pierre Boucher · [contact@spboucher.ai](mailto:contact@spboucher.ai) | ||
| 288 | − | ||||
| 289 | −Un service **Groupe Ka** | ||||
| 290 | 131 | ||||
| 291 | −</div> | 132 | +*Ce dépôt vit sur **spbgit** (git perso — https://git.spboucher.ai). Estimations statistiques à titre indicatif — elles ne remplacent pas une évaluation par un évaluateur agréé (OEAQ).* | ||
added
docs/screenshots/vrai-prix-desktop.png
+0 −0
Binary file not shown.
added
docs/screenshots/vrai-prix-mobile.png
+0 −0
Binary file not shown.