SPB Git forge

spb/auto-ka

Public
61commits 1branches 0releases
14.4 MBsize
maindefault branch
12 days agolast push
Python 61.6% TypeScript 20.9% CSS 11.4% JavaScript 5.1% HTML 1.1%

README refait au complet — métriques live + 6 captures + sections SEO/KA ID

- Métriques de production à jour : 17 698 véhicules (17 082 autos, 591 motos,
  25 scooters), 138 concessionnaires, 83 marques, 72 villes, ~16 photos/véh.,
  prix 99,6 %, VIN 95,1 %, 18 475 URLs indexables
- 6 captures fraîches (accueil, fiche véhicule, stats, motos, page
  programmatique Toyota, mobile) prises sur www.auto-ka.com
- Nouvelles sections : référencement programmatique (tableau des gabarits
  d'URL, JSON-LD, 410/404, sitemaps), verticales motos/scooters, compte
  KA ID + favoris hub, mobile
- Badges SEO/KA ID, architecture mermaid avec couche SSR + Googlebot,
  principe n°6 « honnêteté envers les moteurs »

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Simon-Pierre Boucher committed 1 mo ago (Aug 13, 2026) parent b68be31

7 changed files +137 −35

modified README.md +137 −35
@@ -7,21 +7,26 @@
7 7 **[www.auto-ka.com](https://www.auto-ka.com)**
8 8
9 9 ![Python](https://img.shields.io/badge/Python-3.14-17181c?style=for-the-badge&logo=python&logoColor=ff5a2a)
10 −![FastAPI](https://img.shields.io/badge/FastAPI-API-17181c?style=for-the-badge&logo=fastapi&logoColor=ff5a2a)
10 +![FastAPI](https://img.shields.io/badge/FastAPI-API_+_SSR-17181c?style=for-the-badge&logo=fastapi&logoColor=ff5a2a)
11 11 ![React](https://img.shields.io/badge/React_18-Vite_+_TS-17181c?style=for-the-badge&logo=react&logoColor=ff5a2a)
12 −![SQLite](https://img.shields.io/badge/SQLite-storage-17181c?style=for-the-badge&logo=sqlite&logoColor=ff5a2a)
12 +![SQLite](https://img.shields.io/badge/SQLite-diff_engine-17181c?style=for-the-badge&logo=sqlite&logoColor=ff5a2a)
13 13 ![PM2](https://img.shields.io/badge/PM2-production-17181c?style=for-the-badge&logoColor=ff5a2a)
14 14
15 −![Véhicules](https://img.shields.io/badge/v%C3%A9hicules_en_vente-15_970-cc3f16?style=flat-square)
16 −![Concessionnaires](https://img.shields.io/badge/concessionnaires_connect%C3%A9s-124-cc3f16?style=flat-square)
15 +![Véhicules](https://img.shields.io/badge/v%C3%A9hicules_en_vente-17_698-cc3f16?style=flat-square)
16 +![Concessionnaires](https://img.shields.io/badge/concessionnaires_connect%C3%A9s-138-cc3f16?style=flat-square)
17 17 ![Régions](https://img.shields.io/badge/r%C3%A9gions_couvertes-18-cc3f16?style=flat-square)
18 −![Prix](https://img.shields.io/badge/annonces_avec_prix-100%25-cc3f16?style=flat-square)
19 −![Connecteurs](https://img.shields.io/badge/connecteurs_actifs-125-cc3f16?style=flat-square)
18 +![Marques](https://img.shields.io/badge/marques-83-cc3f16?style=flat-square)
19 +![Prix](https://img.shields.io/badge/annonces_avec_prix-99,6_%25-cc3f16?style=flat-square)
20 20
21 −*Agrégateur indépendant de voitures usagées — chaque annonce avec ses photos,
22 −ses caractéristiques standardisées (année, km, transmission, carburant, VIN…)
23 −et un lien direct vers l'annonce originale du concessionnaire. Toujours à
24 −jour, automatiquement. Suivi des baisses de prix intégré.*
21 +![SEO](https://img.shields.io/badge/URLs_indexables-18_475-17181c?style=flat-square&logo=googlesearchconsole&logoColor=ff5a2a)
22 +![Sitemap](https://img.shields.io/badge/sitemap.xml-dynamique-17181c?style=flat-square&logoColor=ff5a2a)
23 +![JSON-LD](https://img.shields.io/badge/JSON--LD-Car_·_Offer_·_ItemList-17181c?style=flat-square&logoColor=ff5a2a)
24 +![KA ID](https://img.shields.io/badge/KA_ID-SSO_Groupe_KA-17181c?style=flat-square&logoColor=ff5a2a)
25 +
26 +*Agrégateur indépendant de voitures, motos et scooters usagés — chaque annonce
27 +avec ses photos, ses caractéristiques standardisées (année, km, transmission,
28 +carburant, VIN…) et un lien direct vers l'annonce originale du concessionnaire.
29 +Toujours à jour, automatiquement. Suivi des baisses de prix intégré.*
25 30
26 31 <img src="docs/screenshot-home.png" alt="Auto-Ka — recherche de véhicules" width="920" />
27 32
@@ -40,54 +45,136 @@ chaque véhicule vers un schéma unique et détecte les changements en continu.
40 45 > Les sites de concessionnaires n'offrent pas de webhooks. Auto-Ka reproduit
41 46 > l'équivalent : **synchronisation périodique + hash de contenu** → arrivages,
42 47 > baisses de prix et ventes détectés automatiquement. Un véhicule qui disparaît
43 −> du site source est marqué vendu dans Auto-Ka.
48 +> du site source est marqué vendu dans Auto-Ka — et sa page renvoie alors un
49 +> vrai `410 Gone` aux moteurs de recherche.
44 50
45 51 ## Les chiffres
46 52
47 53 | Métrique | Valeur |
48 54 |---|---|
49 −| Véhicules en vente | **15 970** |
50 −| Concessionnaires connectés | **124** (125 connecteurs) |
51 −| Régions administratives couvertes | **18** |
52 −| Annonces avec prix affiché | **100 %** (jamais de prix inventé) |
53 −| Annonces avec kilométrage | **99,9 %** |
54 −| Photos par véhicule (moyenne) | **~11** (galeries complètes en cours d'enrichissement) |
55 −| Annonces avec description | **72 %** · équipements **44 %** · moteur **66 %** |
55 +| Véhicules en vente | **17 698** — 17 082 autos · 591 motos · 25 scooters |
56 +| Concessionnaires connectés | **138** (125 autos + 13 motos/scooters) |
57 +| Régions administratives couvertes | **18** · **72 villes** · **83 marques** |
58 +| Annonces avec prix affiché | **99,6 %** (jamais de prix inventé) |
59 +| Annonces avec kilométrage | **99,7 %** · VIN **95,1 %** |
60 +| Annonces avec description | **85 %** · équipements **72 %** |
61 +| Photos par véhicule (moyenne) | **~16** (galeries complètes) |
62 +| Prix moyen / médian du parc | **28 529 $** / **24 995 $** |
63 +| URLs indexables (SEO) | **18 475** — 17 698 fiches + 777 pages de recherche |
56 64 | Cycle de rafraîchissement | **2 h** (PM2 watcher + enrichissement progressif) |
57 65
66 +## La fiche véhicule
67 +
68 +Galerie photos complète, caractéristiques standardisées, VIN, équipements,
69 +**historique de prix**, véhicules similaires toutes sources confondues, favoris
70 +KA ID — et le lien vers l'annonce originale, toujours.
71 +
72 +<div align="center">
73 +<img src="docs/screenshot-vehicle.png" alt="Auto-Ka — fiche véhicule : galerie, caractéristiques, VIN, lien source" width="920" />
74 +</div>
75 +
76 +## Le marché en direct
77 +
78 +Tuiles de synthèse, distribution des prix, répartitions par région / marque /
79 +carrosserie, baisses de prix récentes — et un **rapport PDF** généré à la
80 +demande (`autoka/pdfgen.py`).
81 +
82 +<div align="center">
83 +<img src="docs/screenshot-stats.png" alt="Auto-Ka — statistiques du marché et distribution des prix" width="920" />
84 +</div>
85 +
86 +## Trois verticales, un moteur
87 +
88 +Le champ `kind` (`auto` / `moto` / `scooter`) traverse tout le pipeline —
89 +connecteurs, base, API, frontend. Les motos et scooters ont leurs onglets
90 +dédiés, alimentés par 13 concessionnaires sur plateforme **PowerGo**.
91 +
92 +<div align="center">
93 +<img src="docs/screenshot-motos.png" alt="Auto-Ka — verticale motos usagées" width="920" />
94 +</div>
95 +
58 96 ## L'architecture en 30 secondes
59 97
60 98 ```mermaid
61 99 flowchart LR
62 − subgraph Sources["99 concessionnaires"]
63 − S1["D2C Media ×50 · SM360 ×8<br/>AMVOQ ×6 · EvalAuto ×11<br/>Convertus ×4 · customs<br/>HGrégoire · AED · Beaucage…"]
100 + subgraph Sources["138 concessionnaires"]
101 + S1["D2C Media ×50 · SM360 ×8<br/>AMVOQ ×6 · EvalAuto ×11<br/>Convertus ×4 · PowerGo ×13<br/>HGrégoire · AED · customs…"]
64 102 end
65 103 subgraph AutoKa["Auto-Ka"]
66 104 C["Connecteurs<br/><i>1 adaptateur / plateforme</i>"] --> N["Normalisation<br/><i>schéma Vehicle unique</i>"]
67 105 N --> D[("SQLite<br/>hash + diff + prix")]
68 106 D --> A["API FastAPI<br/>/api/vehicles · /api/facets"]
69 − A --> F["React 18 + Vite<br/>filtres auto · fiches · stats"]
107 + D --> SEO["Rendu serveur SEO<br/><i>HTML complet + JSON-LD<br/>sitemaps · 410 · canonical</i>"]
108 + A --> F["React 18 + Vite<br/>filtres · fiches · stats"]
109 + SEO --> F
70 110 end
71 111 W["⏱ Watcher 2 h<br/>(PM2)"] -.-> C
72 112 S1 --> C
73 113 F --> U["🔑 Acheteur"]
114 + SEO --> G["🕷 Googlebot"]
74 115 ```
75 116
76 117 | Couche | Rôle | Fichiers |
77 118 |---|---|---|
78 −| **Connecteurs** | 1 module par plateforme de site (D2C Media, SM360, AMVOQ Focus 360, EvalAuto Gatsby/Next.js, Convertus VMS, ADWS, EDealer…) avec 1 sous-classe par concessionnaire ; JSON-LD schema.org, API JSON internes, sitemaps ; Firecrawl pour les sites derrière Cloudflare | `autoka/connectors/*.py` |
79 −| **Schéma** | `Vehicle` standardisé : marque, modèle, année, prix, km, transmission, carburant, motricité, carrosserie, couleurs, VIN, photos, région | `autoka/schema.py` |
119 +| **Connecteurs** | 1 module par plateforme de site (D2C Media, SM360, AMVOQ Focus 360, EvalAuto Gatsby/Next.js, Convertus VMS, ADWS, EDealer, PowerGo…) avec 1 sous-classe par concessionnaire ; JSON-LD schema.org, API JSON internes, sitemaps ; Firecrawl/Scrapfly pour les sites derrière Cloudflare | `autoka/connectors/*.py` |
120 +| **Schéma** | `Vehicle` standardisé : marque, modèle, année, prix, km, transmission, carburant, motricité, carrosserie, couleurs, VIN, photos, région, `kind` | `autoka/schema.py` |
80 121 | **Normalisation** | Prix/km/année depuis le texte, marques canoniques, ville → région administrative, inférence motricité/carburant depuis les badges du titre (AWD, PHEV…) | `autoka/normalize.py` |
81 122 | **Diff engine** | Upsert par hash de contenu — nouveau / modifié / vendu (délai de grâce 2 syncs), **historique de prix**, détection de dérive | `autoka/db.py` |
82 −| **API** | Filtres marque / modèle / année / prix / km / carburant / motricité / région / concessionnaire, facettes, stats marché, baisses de prix récentes | `autoka/web.py` |
83 −| **Frontend** | Design « éditorial sharp », accent orange racing : filtres auto complets, fiches avec galerie photos, historique de prix et véhicules similaires | `frontend/` |
123 +| **API** | Filtres marque / modèle / année / prix / km / carburant / motricité / région / ville / concessionnaire, facettes, stats marché, baisses de prix | `autoka/web.py` |
124 +| **SEO / SSR** | HTML complet servi dès la 1ʳᵉ requête, meta uniques, JSON-LD, pages programmatiques, sitemaps dynamiques, 410/404 | `autoka/seo.py` |
125 +| **Compte** | SSO **KA ID** (hub groupe-ka.com), profil Groupe KA, favoris « Mon univers Ka » centralisés | `autoka/auth.py` · `hubprofile.py` · `hubfav.py` |
126 +| **Frontend** | Design « éditorial sharp », accent orange racing : filtres auto complets, fiches avec galerie, historique de prix et similaires | `frontend/` |
84 127
85 −## Le marché en direct
128 +## Référencement : chaque recherche a sa page
129 +
130 +Le site est une SPA React, mais **les moteurs de recherche ne voient jamais une
131 +page vide** : `autoka/seo.py` intercepte chaque route publique et sert le HTML
132 +complet — title et meta description uniques, canonical, Open Graph, hreflang
133 +`fr-CA`, données structurées et le contenu intégral (24 fiches, stats, liens)
134 +dans `#root`. React monte ensuite par-dessus et reprend la main.
86 135
87 136 <div align="center">
88 −<img src="docs/screenshot-stats.png" alt="Auto-Ka — statistiques du marché et baisses de prix" width="920" />
137 +<img src="docs/screenshot-seo-marque.png" alt="Auto-Ka — page programmatique Toyota usagées à vendre au Québec" width="920" />
89 138 </div>
90 139
140 +**~900 pages programmatiques**, alignées sur les recherches réelles, maillées
141 +entre elles (modèles voisins, autres marques, villes de la région) :
142 +
143 +| Gabarit d'URL | Exemple | Contenu |
144 +|---|---|---|
145 +| `/usagees/{marque}` | `/usagees/toyota` | H1, nombre d'annonces, prix moyen/médian, 24 fiches, modèles de la marque |
146 +| `/usagees/{marque}/{modele}` | `/usagees/honda/civic` | idem, ciblé modèle (fil d'Ariane complet) |
147 +| `/region/{region}` | `/region/monteregie` | inventaire de la région + liens vers ses villes |
148 +| `/ville/{ville}` | `/ville/sherbrooke` | inventaire de la ville + villes voisines |
149 +| `/carrosserie/{type}` | `/carrosserie/vus` | liste blanche de 10 carrosseries propres |
150 +| `/motos/{marque}` · `/scooters/{marque}` | `/motos/harley-davidson` | verticales moto/scooter |
151 +
152 +**Fiches** : URL lisible `/vehicule/{uid}/{annee-marque-modele}` (301 depuis
153 +l'uid nu), JSON-LD `Car`/`Motorcycle` + `Offer` complet (prix CAD, km, VIN,
154 +concessionnaire, ville), `BreadcrumbList`, og:image.
155 +
156 +**Cycle de vie honnête** : véhicule vendu → **410 Gone** avec liens vers la
157 +page modèle parente ; URL inconnue → vrai **404** (fin des soft-404).
158 +
159 +**Découvrabilité** : `robots.txt` + `sitemap.xml` dynamique (index →
160 +`pages.xml` + `vehicules-N.xml` par tranches de 10 000, `lastmod` réels) —
161 +**18 475 URLs** régénérées à la volée. Compression gzip, images lazy avec
162 +dimensions explicites.
163 +
164 +```bash
165 +$ curl -s https://www.auto-ka.com/usagees/toyota | grep -o "<title>[^<]*"
166 +<title>Toyota usagées à vendre au Québec — 1 163 en inventaire | Auto·Ka
167 +```
168 +
169 +## Compte KA ID — l'identité du Groupe KA
170 +
171 +Connexion **« Se connecter avec KA ID »** via le hub
172 +[groupe-ka.com](https://www.groupe-ka.com) : le même compte (et le même
173 +`ka-…`) sur toutes les plateformes du groupe. Page **/profil** avec la carte
174 +de membre Groupe KA, profil enrichi lu depuis le hub, et **favoris ♥
175 +« Mon univers Ka »** — posés sur n'importe quelle carte ou fiche, stockés
176 +centralement, visibles depuis toutes les plateformes.
177 +
91 178 ## Démarrage rapide
92 179
93 180 ```bash
@@ -125,26 +212,37 @@ class MonConcessionnaire(D2CConnector):
125 212 ```
126 213
127 214 Puis : `.venv/bin/python run.py sync monconcessionnaire` — et l'inventaire
128 −apparaît sur le site avec fiches, galeries et liens sources. Ajoutez l'entrée
129 −correspondante dans `data/sources.json` pour la page **Sources**.
215 +apparaît sur le site avec fiches, galeries, liens sources… et dans le sitemap.
216 +Ajoutez l'entrée correspondante dans `data/sources.json` pour la page
217 +**Sources**.
130 218
131 219 ## API
132 220
133 221 | Endpoint | Description |
134 222 |---|---|
135 −| `GET /api/vehicles?make=&model=&region=&price_max=&km_max=&fuel=&sort=` | Recherche filtrée et triée |
223 +| `GET /api/vehicles?make=&model=&region=&city=&price_max=&km_max=&fuel=&sort=` | Recherche filtrée et triée (`kind=auto\|moto\|scooter`) |
136 224 | `GET /api/vehicles/{uid}` | Fiche complète (photos, historique de prix, similaires) |
137 −| `GET /api/facets?make=` | Valeurs distinctes pour construire les filtres |
225 +| `GET /api/facets?make=&kind=` | Valeurs distinctes pour construire les filtres |
138 226 | `GET /api/sources` | Registre des concessionnaires + compteurs + dernière sync |
139 −| `GET /api/stats` | Totaux, moyennes, top marques/régions, baisses de prix récentes |
227 +| `GET /api/stats` · `GET /api/stats/detailed` | Totaux, moyennes, top marques/régions, baisses de prix |
228 +| `GET /api/stats/rapport.pdf` | Rapport PDF « Le marché de l'occasion » |
140 229 | `POST /api/sync` | Déclenche une synchronisation en arrière-plan |
230 +| `GET /api/auth/ka/login` · `/api/favorites` | SSO KA ID + favoris hub |
231 +| `GET /robots.txt` · `/sitemap.xml` | SEO — sitemaps dynamiques avec lastmod |
232 +
233 +## Mobile d'abord (aussi)
234 +
235 +<div align="center">
236 +<img src="docs/screenshot-mobile.png" alt="Auto-Ka — version mobile" width="320" />
237 +</div>
141 238
142 239 ## Couverture
143 240
144 241 **Grands réseaux** — HGrégoire (mégacentres partout au Québec), Automobile En
145 242 Direct, Occasion Beaucage (7 concessions), Le Prix du Gros, Méga Centre de
146 243 liquidation, St-Jérôme Auto Dépôt, Ste-Foy Chrysler, Desmeules, Entrepôt Auto
147 −Durocher…
244 +Durocher… **Motos & scooters** — Motos Illimitées, concessionnaires
245 +Harley-Davidson, Honda, Yamaha, Kawasaki, BMW, Vespa via PowerGo.
148 246
149 247 **Toutes les régions** — Montérégie, Capitale-Nationale, Laurentides, Mauricie,
150 248 Laval, Estrie, Outaouais, Centre-du-Québec, Chaudière-Appalaches, Lanaudière,
@@ -160,7 +258,7 @@ groupe, vérifié par VIN).
160 258 Déployé sous **PM2** (3 processus) derrière **ngrok** :
161 259
162 260 ```
163 −auto-ka-web .venv/bin/python run.py serve 8095 # API + frontend
261 +auto-ka-web .venv/bin/python run.py serve 8095 # API + frontend + SSR SEO
164 262 auto-ka-sync .venv/bin/python run.py watch 120 # resync 2 h
165 263 auto-ka-ngrok ngrok http --url=www.auto-ka.com 8095 # tunnel
166 264 ```
@@ -180,6 +278,9 @@ ses données lui-même.**
180 278 5. **Robustesse** — un connecteur qui casse n'affecte jamais les autres ;
181 279 un 404 (véhicule vendu) ne bloque jamais une source ; détection de dérive
182 280 (chute de volume → retraits suspendus + alerte).
281 +6. **Honnêteté envers les moteurs** — le HTML servi aux robots est le même
282 + que celui servi aux humains ; un véhicule vendu répond 410, une page
283 + inexistante 404.
183 284
184 285 ---
185 286
@@ -193,7 +294,8 @@ ses données lui-même.**
193 294 [![Git](https://img.shields.io/badge/git.spboucher.ai-17181c?style=for-the-badge&logo=git&logoColor=ff5a2a)](https://git.spboucher.ai)
194 295
195 296 *Conçu, construit et déployé en une journée — du sondage de plateformes
196 −(60+ sites classifiés) aux 99 connecteurs en production.*
297 +(60+ sites classifiés) aux 138 connecteurs, trois verticales et 18 475 pages
298 +indexables en production.*
197 299
198 300 © 2026 Simon-Pierre Boucher — tous droits réservés.
199 301
modified docs/screenshot-home.png +0 −0

Binary file not shown.

added docs/screenshot-mobile.png +0 −0

Binary file not shown.

added docs/screenshot-motos.png +0 −0

Binary file not shown.

added docs/screenshot-seo-marque.png +0 −0

Binary file not shown.

modified docs/screenshot-stats.png +0 −0

Binary file not shown.

added docs/screenshot-vehicle.png +0 −0

Binary file not shown.