SPB Git forge

spb/valoplex

Public

ValoPlex — moteur d'évaluation spécialisé pour les plex au Québec, petit frère de Vrai-Prix.

11commits 1branches 0releases
2.4 MBsize
maindefault branch
20 days agolast push
TypeScript 91.9% Python 6% CSS 2.1%

docs: README ultra détaillé + visite guidée en 10 captures (2026-08-28) + gitignore données renforcé

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Simon-Pierre Boucher committed 27 days ago (Aug 29, 2026) parent 3493ea7

13 changed files +189 −29

modified .gitignore +17 −0
@@ -15,3 +15,20 @@ models/
15 15 app/test-results/
16 16 app/playwright-report/
17 17 __pycache__/
18 +
19 +# données & secrets — ceinture et bretelles (2026-08-28)
20 +*.db
21 +*.db-shm
22 +*.db-wal
23 +*.sqlite
24 +*.sqlite3
25 +*.joblib
26 +*.parquet
27 +*.pkl
28 +.env
29 +.env.*
30 +*.pem
31 +*.key
32 +node_modules/
33 +.venv/
34 +venv/
modified README.md +160 −29
@@ -13,40 +13,89 @@
13 13 ![Next.js](https://img.shields.io/badge/Next.js-16-141814?style=flat-square&logo=nextdotjs)
14 14 ![TypeScript](https://img.shields.io/badge/TypeScript-strict-141814?style=flat-square&logo=typescript)
15 15
16 −**En production : [www.valoplex.com](https://www.valoplex.com)** · petit frère spécialisé de [Vrai-Prix](https://www.vrai-prix.com)
16 +**En production : [www.valoplex.com](https://www.valoplex.com)** · un service **Groupe Ka** · petit frère spécialisé de [Vrai-Prix](https://www.vrai-prix.com)
17 17
18 18 ---
19 19
20 −## Aperçu
20 +## Visite guidée
21 21
22 −*Captures du 2026-08-25 (mobile 390×844 · desktop 1440×900).*
22 +*Captures du 2026-08-28 — desktop 1440×900, mobile 390×844.*
23 23
24 −### Mobile
24 +### 1 · Accueil — « Votre plex vaut combien, porte par porte ? »
25 25
26 −<table>
27 − <tr>
28 − <td align="center"><img src="docs/screenshots/mobile/home.webp" width="240" alt="Accueil mobile"><br><sub><b>Accueil — « Votre plex vaut combien, porte par porte ? »</b></sub></td>
29 − <td align="center"><img src="docs/screenshots/mobile/parc.webp" width="240" alt="Parc mobile"><br><sub><b>Évaluation de parc multi-plex</b></sub></td>
30 − <td align="center"><img src="docs/screenshots/mobile/stats.webp" width="240" alt="Stats mobile"><br><sub><b>Statistiques du marché plex</b></sub></td>
31 − </tr>
32 −</table>
26 +![Accueil](docs/screenshots/01-accueil.jpg)
27 +
28 +Le hero éditorial pose la promesse : un moteur **spécialisé plex** (Québec, 2021-2026), pas un estimateur généraliste. Bandeau-marquee des chiffres clés (1 733 744 portes, 91 060 ventes, fourchette P10-P90 calibrée à 80 %, « zéro boîte noire »), compteurs officiels, puis la **recherche d'adresse plein texte** sur les 393 867 plex indexés (FTS5). Sources affichées en toutes lettres : rôles d'évaluation foncière du Québec (MAMH) et ventes de plex publiées.
29 +
30 +### 2 · Ka · agent IA — « il pense en portes, en cashflow et en TGA »
31 +
32 +![Agent Ka](docs/screenshots/02-ka.jpg)
33 +
34 +`/ka` : l'agent conversationnel de la maison, propulsé par Claude. **13 outils** branchés sur le registre, le moteur d'évaluation et le pro forma : on lui donne une adresse, il retrouve le plex, l'évalue porte par porte, puis monte le pro forma investisseur complet (loyer implicite, hypothèque, DSCR, projection 5 ans) — réponse **en streaming**, suggestions prêtes à cliquer.
35 +
36 +### 3 · Méthodologie — le calcul, montré en entier
37 +
38 +![Méthodologie](docs/screenshots/03-methodologie.jpg)
39 +
40 +`/methodologie` : la page qui tient la promesse « zéro boîte noire » — modèle hédonique en ratio `log(prix / valeur au rôle)`, rétrécissement hors domaine au-delà de 12 portes, calibration conforme des fourchettes par gabarit, validation IAAO sur ventes jamais vues. Tout le raisonnement du moteur, expliqué au lecteur.
41 +
42 +### 4 · Statistiques — 400 638 996 500 $, au dollar près
43 +
44 +![Statistiques](docs/screenshots/04-stats.jpg)
45 +
46 +`/stats` : la somme des 393 867 estimations ValoPlex — **400,6 G$** de plex au Québec (millésime 2026), soit 43 973 $ par Québécois·e, ×2,4 budgets annuels de la province, +40 % depuis 2021 à périmètre constant. Valeur médiane 751 900 $, 128,5 km² de plancher bâti, 1 124,6 km² de terrains, 1 065 municipalités. Rapport statistique provincial en PDF + **rapport personnalisé** à la carte.
47 +
48 +### 5 · Parc immobilier — le portefeuille au complet
49 +
50 +![Parc](docs/screenshots/05-parc.jpg)
51 +
52 +`/parc` : pour les propriétaires multiples et investisseurs — on ajoute jusqu'à **40 plex**, ValoPlex évalue chaque immeuble puis agrège le parc (valeur totale, fourchette, croissance 2021→2026) et produit un **rapport PDF consolidé**.
53 +
54 +### 6 · Conditions d'utilisation
55 +
56 +![Conditions](docs/screenshots/06-conditions.jpg)
57 +
58 +`/conditions` : cadre d'usage honnête — estimations statistiques à titre indicatif qui ne remplacent ni une évaluation par un évaluateur agréé (OEAQ) ni un conseil financier, licence des données ouvertes MAMH, limites de responsabilité.
59 +
60 +### 7 · Politique de confidentialité
61 +
62 +![Confidentialité](docs/screenshots/07-confidentialite.jpg)
63 +
64 +`/confidentialite` : données collectées, témoins (bannière de consentement), compte KA ID, droits des utilisateurs — rédigée pour le cadre québécois (Loi 25).
65 +
66 +### 8 · Favoris — « Mon univers Ka »
67 +
68 +![Favoris](docs/screenshots/08-favoris.jpg)
69 +
70 +`/favoris` : les plex sauvegardés d'un cœur, rattachés au **compte KA ID** (l'identité unique du Groupe Ka — courriel, Google ou Apple) et synchronisés dans « Mon univers Ka » à travers tout l'écosystème.
71 +
72 +### 9 · Accueil (suite) — le plan B et les trois promesses
33 73
34 −### Desktop
74 +![Accueil section 2](docs/screenshots/09-accueil-section-1.jpg)
75 +
76 +Pas d'adresse ? Le **formulaire descriptif** prend le relais : municipalité, nombre de portes, superficie habitable, année de construction, terrain. En dessous, les trois promesses de la maison : **01 · Spécialisé, pas généraliste** (entraîné exclusivement sur des ventes de plex), **02 · Fourchette calibrée à 80 %** (vérifiée, pas promise), **03 · Le calcul, montré** (chaque ajustement affiché en dollars).
77 +
78 +### 10 · Mobile — la même exigence dans la poche
79 +
80 +<p align="center"><img src="docs/screenshots/10-accueil-mobile.jpg" width="340" alt="Accueil mobile"></p>
81 +
82 +L'accueil en 390×844 : header opaque, menu tactile et zones de touche au **standard mobile Ka** (tokens, dvh, safe-area), recherche et compteurs sans compromis.
83 +
84 +<details>
85 +<summary><b>Galerie complémentaire (campagne du 2026-08-25, WebP)</b></summary>
35 86
36 87 <table>
37 88 <tr>
38 − <td align="center"><img src="docs/screenshots/desktop/home.webp" width="420" alt="Accueil desktop"><br><sub><b>Accueil — 393 867 plex, 1 733 744 portes, 91 060 ventes</b></sub></td>
39 − <td align="center"><img src="docs/screenshots/desktop/parc.webp" width="420" alt="Parc desktop"><br><sub><b>Parc — évaluation consolidée multi-adresses</b></sub></td>
40 − </tr>
41 − <tr>
42 − <td align="center"><img src="docs/screenshots/desktop/ka.webp" width="420" alt="Agent Ka"><br><sub><b>Ka · agent IA spécialisé plex</b></sub></td>
43 − <td align="center"><img src="docs/screenshots/desktop/favoris.webp" width="420" alt="Favoris"><br><sub><b>Favoris « Mon univers Ka » (KA ID)</b></sub></td>
44 − </tr>
45 − <tr>
46 − <td align="center" colspan="2"><img src="docs/screenshots/desktop/stats.webp" width="640" alt="Stats"><br><sub><b>Statistiques — ventes réelles 2021-2026, sans boîte noire</b></sub></td>
89 + <td align="center"><img src="docs/screenshots/mobile/home.webp" width="180" alt="Accueil mobile"><br><sub>Accueil</sub></td>
90 + <td align="center"><img src="docs/screenshots/mobile/parc.webp" width="180" alt="Parc mobile"><br><sub>Parc</sub></td>
91 + <td align="center"><img src="docs/screenshots/mobile/stats.webp" width="180" alt="Stats mobile"><br><sub>Stats</sub></td>
92 + <td align="center"><img src="docs/screenshots/mobile/ka.webp" width="180" alt="Ka mobile"><br><sub>Agent Ka</sub></td>
93 + <td align="center"><img src="docs/screenshots/mobile/favoris.webp" width="180" alt="Favoris mobile"><br><sub>Favoris</sub></td>
47 94 </tr>
48 95 </table>
49 96
97 +</details>
98 +
50 99 ## Pourquoi un moteur spécialisé plex ?
51 100
52 101 Un plex est un **immeuble à revenus** : sa valeur se pense par porte, par revenu, par TGA — pas comme une unifamiliale. ValoPlex couvre **tous** les immeubles résidentiels multi-logements du Québec (CUBF 1000, 2 logements et plus — du duplex à la tour) avec un modèle et une interface dédiés à cette logique.
@@ -60,17 +109,22 @@ Un plex est un **immeuble à revenus** : sa valeur se pense par porte, par reven
60 109 | 📍 Adresses officielles | Toutes les inscriptions d'adresses de l'unité (table des adresses du rôle) |
61 110 | ⚖️ Ajustement portes | 4ᵉ ajustement des comparables : 50 % du prix/porte, plafonné ±30 % |
62 111 | 🗺️ Plan des comparables | Carte plan d'arpenteur SVG (azimut + distance réels), état vide honnête si aucun plex comparable |
63 −| 📄 Rapports PDF | Standard 3 p. (avec pro forma), professionnel bancaire 6 p., parc, statistique provincial |
112 +| 📄 Rapports PDF | Standard 3 p. (avec pro forma), professionnel bancaire 6 p., parc, statistique provincial, personnalisé |
64 113 | 📉 Statistiques | Les plex du Québec valent **400,6 G$** — répartition par gabarit et par municipalité |
114 +| 🤖 Ka · agent IA | 13 outils (registre, moteur, pro forma), streaming, garde anti-hallucination, liens PDF fiables |
115 +| ♥ Favoris KA ID | SSO Groupe Ka (courriel, Google, Apple), favoris synchronisés « Mon univers Ka » |
116 +| 🌐 Bilingue | Interface FR/EN (bascule instantanée, contexte de langue côté client) |
65 117
66 118 ## Le modèle : hédonique en ratio, calibré par gabarit
67 119
68 −Trois idées font la différence :
120 +Gradient boosting **LightGBM** (objectif L1) entraîné sur **91 060 ventes réelles de plex** (2021-2026). Trois idées font la différence :
69 121
70 122 1. **Cible en ratio `log(prix / valeur au rôle)`** — pas le prix. Un modèle en prix brut, dominé par la masse des duplex, écrase les grands immeubles (nous avons mesuré une tour au rôle de 705 M$ prédite… 5,6 M$). En ratio, le duplex de 400 k$ et la tour de 700 M$ sont évalués avec la même justesse relative. Le modèle connaît en plus **l'ancienneté du rôle** (mois depuis la date des conditions du marché du dénominateur).
71 123 2. **Rétrécissement hors domaine** : au-delà de 12 portes (données de ventes rares), l'estimation glisse vers l'ancre empirique de sa bande de gabarit (poids du modèle : 55 % → 20 %).
72 124 3. **Calibration conforme Mondrian** : les fourchettes P10–P90 sont calibrées **par bande de portes** sur un ensemble de calibration dédié — couverture vérifiée de **80,0 %** (pas promise : mesurée).
73 125
126 +À côté du modèle, le moteur de **comparables** sélectionne des ventes de plex proches et affiche chaque ajustement en dollars — marché (indice municipal), superficie, âge, et le 4ᵉ ajustement signature : les **portes**.
127 +
74 128 ### Validation (norme IAAO, 13 617 ventes de test jamais vues)
75 129
76 130 | Segment | MdAPE | Ratio médian |
@@ -96,16 +150,70 @@ Approche revenu **inversée** : quelle structure de revenus la valeur estimée s
96 150
97 151 Cinq curseurs (taux, mise de fonds, amortissement, TGA, appréciation) — tout recalcule en direct.
98 152
153 +## Pages
154 +
155 +| Route | Contenu |
156 +|---|---|
157 +| `/` | Accueil : recherche d'adresse (FTS5) + formulaire descriptif « plan B » |
158 +| `/estimation/[id]` | Fiche d'estimation d'un plex du registre : valeur + fourchette P10-P90, frise des portes, comparables ajustés, plan d'arpenteur, pro forma, rapports PDF |
159 +| `/estimation/manuelle` | Estimation sans adresse (municipalité, portes, superficies, année) |
160 +| `/parc` | Évaluation consolidée d'un parc (jusqu'à 40 plex) + rapport PDF |
161 +| `/stats` | Statistiques provinciales : 400,6 G$, gabarits, 200 municipalités, rapports PDF |
162 +| `/ka` | Ka · agent IA conversationnel (13 outils, streaming) |
163 +| `/favoris` | Favoris « Mon univers Ka » (compte KA ID) |
164 +| `/methodologie` | Méthodologie complète du modèle et des comparables |
165 +| `/conditions` · `/confidentialite` | Pages légales (FR/EN) |
166 +
167 +## API
168 +
169 +Toutes les routes sous `app/src/app/api/` (App Router Next.js) :
170 +
171 +| Endpoint | Méthodes | Rôle |
172 +|---|---|---|
173 +| `/api/search` | GET | Recherche plein texte d'adresses (FTS5) |
174 +| `/api/estimate` | GET `?id=` / POST | Estimation d'une unité du registre / estimation manuelle (municipalité, portes, superficies, année) |
175 +| `/api/portfolio` | POST | Évaluation agrégée d'un parc |
176 +| `/api/report` | POST | Rapport PDF standard (3 p., avec pro forma) |
177 +| `/api/report/pro` | POST | Rapport PDF professionnel bancaire (6 p.) |
178 +| `/api/report/portfolio` | POST | Rapport PDF de parc |
179 +| `/api/report/stats` | GET | Rapport statistique provincial (PDF) |
180 +| `/api/stats` · `/api/stats/catalog` · `/api/stats/report/custom` | GET/POST | Statistiques, catalogue de métriques, rapport PDF personnalisé |
181 +| `/api/ka` | POST | Agent Ka (streaming, 13 outils) |
182 +| `/api/favorites` · `/api/favorites/toggle` | GET/POST | Favoris KA ID |
183 +| `/api/auth/ka/login` · `/api/auth/ka/callback` · `/api/auth/me` · `/api/auth/logout` | GET/POST | SSO KA ID (hub Groupe Ka) |
184 +| `/api/lead` | POST | Demandes de contact (stockées côté base) |
185 +
186 +Les PDF sont générés côté serveur avec **pdfkit** et les polices embarquées du dépôt (`app/assets/fonts/` : Space Grotesk, Inter, JetBrains Mono).
187 +
188 +## Données
189 +
190 +Base **SQLite** unique (`app/data/valoplex.db`, ~181 Mo, WAL — non versionnée), interrogée avec better-sqlite3 :
191 +
192 +| Table | Contenu |
193 +|---|---|
194 +| `units` | 393 867 plex (rôle MAMH, CUBF 1000, 2+ logements) : adresses, portes, superficies, année, valeurs au rôle, estimation 2021-2026 + P10/P90 |
195 +| `transactions` | 91 060 ventes réelles de plex 2021-2026 (comparables) |
196 +| `market_index` | Indices de marché municipaux (ajustement temporel des comparables) |
197 +| `units_fts` | Index FTS5 des adresses (la recherche de l'accueil) |
198 +| `leads` | Demandes de contact (jamais versionné, données personnelles) |
199 +
200 +Source : [rôles d'évaluation foncière du Québec](https://www.donneesquebec.ca/recherche/dataset/roles-d-evaluation-fonciere-du-quebec) (MAMH, licence ouverte) + ventes de plex publiées.
201 +
99 202 ## Structure du dépôt
100 203
101 204 ```
102 205 valoplex/
103 206 ├── app/ # application Next.js 16 (TypeScript strict, Tailwind 4)
104 −│ ├── src/lib/ # engine.ts (comparables), proforma.ts, report*.ts (pdfkit)
105 −│ ├── src/components/ # RadarMap, MetricViz, Proforma, DoorsRow…
106 −│ └── src/app/ # pages + API routes
207 +│ ├── src/lib/ # engine.ts (comparables), estimator.ts, proforma.ts,
208 +│ │ # report*.ts (pdfkit), ka/tools.ts (outils de l'agent),
209 +│ │ # ka-auth.ts + hubfav.ts (SSO KA ID), i18n.ts, db.ts
210 +│ ├── src/components/ # RadarMap, MetricViz, Proforma, EstimateForm, KaChat,
211 +│ │ # StatsView, ReportBuilder, SearchBox, HeaderNav…
212 +│ ├── src/app/ # pages + routes API (App Router)
213 +│ └── assets/fonts/ # polices embarquées pour les PDF
214 +├── docs/screenshots/ # visite guidée (JPG 2026-08-28) + galerie WebP
107 215 └── scripts/ # pipeline données/modèle (Python)
108 − ├── hedonic_plex.py # entraînement (ratio + Mondrian) et prédictions 2021-2026
216 + ├── hedonic_plex.py # entraînement LightGBM (ratio + Mondrian), prédictions 2021-2026
109 217 └── build_valoplex_db.py # base SQLite + stats provinciales
110 218 ```
111 219
@@ -125,11 +233,34 @@ python3 scripts/hedonic_plex.py train && python3 scripts/hedonic_plex.py predict
125 233 python3 scripts/build_valoplex_db.py
126 234 ```
127 235
128 −> **Note données** : base SQLite (165 Mo), modèles entraînés et parquets d'estimation non 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).
236 +> **Note données** : base SQLite, modèles entraînés (`models/`) et parquets d'estimation ne sont **jamais versionnés** (voir `.gitignore`). L'agent Ka requiert une clé API Anthropic et le SSO des favoris une configuration KA ID — via variables d'environnement locales, hors dépôt.
237 +
238 +## Déploiement
239 +
240 +| | |
241 +|---|---|
242 +| **Nœud** | `M3U96a` (MacLustr), app déployée dans `~/apps/valoplex` (contenu de `app/` + `docs/`) |
243 +| **Port** | `8091` (Next.js `next start`) |
244 +| **Process manager** | PM2 : `valoplex` (app) + `valoplex-ngrok` (tunnel) |
245 +| **Domaine** | [www.valoplex.com](https://www.valoplex.com) via ngrok |
246 +| **Dépôt** | spbgit (git perso) — bare `~/srv/git/valoplex.git` sur M3U96a, visible sur git.spboucher.ai |
129 247
130 248 ### Design
131 249
132 −Identité « éditorial sharp » : papier grainé `#f5f3ee`, encre `#141814`, **accent orange vif `#ff9f45`**, ocre brûlé `#b25f16` — sœur chromatique de Vrai-Prix (rouge).
250 +Identité « éditorial sharp » : papier grainé `#f5f3ee`, encre `#141814`, **accent orange vif `#ff9f45`**, ocre brûlé `#b25f16` — sœur chromatique de Vrai-Prix (rouge). Titres Space Grotesk, mono JetBrains, marquee de chiffres clés, ombres franches et surlignages au marqueur orange.
251 +
252 +## Un service Groupe Ka
253 +
254 +ValoPlex porte le badge **« Un service Groupe Ka »** : compte unique [KA ID](https://www.groupe-ka.com), favoris « Mon univers Ka », standards mobile/header/design du groupe. Dans la famille immobilière :
255 +
256 +| Site | Spécialité |
257 +|---|---|
258 +| [Vrai-Prix](https://www.vrai-prix.com) | La valeur de **toute** propriété du Québec (le grand frère généraliste) |
259 +| **ValoPlex** | Les **plex** du Québec, porte par porte (2 logements et plus) |
260 +| [Immo-Ka](https://www.immo-ka.com) | Propriétés à vendre au Québec |
261 +| [Lou-Ka](https://www.lou-ka.com) | Logements à louer au Québec |
262 +| [House-Ka](https://www.house-ka.com) · [Rent-Ka](https://www.rent-ka.com) | Maisons à vendre · loyers, Canada hors Québec |
263 +| [Ka·Stats](https://www.ka-stats.com) | L'observatoire statistique de l'écosystème |
133 264
134 265 ## Auteur
135 266
added docs/screenshots/01-accueil.jpg +0 −0

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

added docs/screenshots/10-accueil-mobile.jpg +0 −0

Binary file not shown.

added docs/screenshots/manifest.txt +12 −0
@@ -0,0 +1,12 @@
1 +01-accueil.jpg :: https://www.valoplex.com/
2 +02-ka.jpg :: https://www.valoplex.com/ka
3 +03-methodologie.jpg :: https://www.valoplex.com/methodologie
4 +04-stats.jpg :: https://www.valoplex.com/stats
5 +05-parc.jpg :: https://www.valoplex.com/parc
6 +06-conditions.jpg :: https://www.valoplex.com/conditions
7 +07-confidentialite.jpg :: https://www.valoplex.com/confidentialite
8 +08-favoris.jpg :: https://www.valoplex.com/favoris
9 +FAIL https://www.valoplex.com/doc :: HTTP 404
10 +FAIL https://www.valoplex.com/contact :: HTTP 404
11 +09-accueil-section-1.jpg :: scroll 900
12 +10-accueil-mobile.jpg :: mobile home
13