docs: README à jour avec screenshot
2 changed files +84 −203
modified
README.md
+84 −203
@@ -2,7 +2,7 @@ | ||
| 2 | 2 | |
| 3 | 3 | # Auto·Ka |
| 4 | 4 | |
| 5 | −### Toutes les voitures usagées à vendre au Québec. Un seul endroit. | |
| 5 | +### **Toutes les voitures usagées à vendre au Québec. Un seul endroit.** | |
| 6 | 6 | |
| 7 | 7 | **[www.auto-ka.com](https://www.auto-ka.com)** |
| 8 | 8 | |
@@ -12,170 +12,89 @@ | ||
| 12 | 12 |  |
| 13 | 13 |  |
| 14 | 14 | |
| 15 | − | |
| 16 | − | |
| 17 | − | |
| 18 | − | |
| 19 | − | |
| 20 | − | |
| 21 | − | |
| 22 | − | |
| 23 | − | |
| 24 | − | |
| 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é.* | |
| 30 | − | |
| 31 | −<img src="docs/screenshot-home.png" alt="Auto-Ka — recherche de véhicules" width="920" /> | |
| 32 | − | |
| 33 | 15 | </div> |
| 34 | 16 | |
| 17 | + | |
| 18 | + | |
| 35 | 19 | --- |
| 36 | 20 | |
| 37 | −## Pourquoi Auto-Ka ? | |
| 21 | +## Description | |
| 38 | 22 | |
| 39 | −Chercher une auto usagée au Québec, c'est ouvrir des dizaines de sites de | |
| 40 | −concessionnaires — chacun avec sa navigation, ses filtres, son format. | |
| 41 | −**Auto-Ka retourne le problème** : un connecteur dédié par commerce visite | |
| 42 | −chaque site **à la source** (aucune plateforme d'annonces revendue), normalise | |
| 43 | −chaque véhicule vers un schéma unique et détecte les changements en continu. | |
| 23 | +**Auto-Ka** est un **agrégateur indépendant de voitures, motos et scooters usagés** couvrant la **province de Québec**. Chercher une auto usagée, c'est normalement ouvrir des dizaines de sites de concessionnaires — chacun avec sa navigation, ses filtres, son format. **Auto-Ka retourne le problème** : un **connecteur dédié par commerce** visite chaque site **à la source** (aucune plateforme d'annonces revendue), **normalise** chaque véhicule vers un **schéma unique** et **détecte les changements en continu**. | |
| 44 | 24 | |
| 45 | −> Les sites de concessionnaires n'offrent pas de webhooks. Auto-Ka reproduit | |
| 46 | −> l'équivalent : **synchronisation périodique + hash de contenu** → arrivages, | |
| 47 | −> baisses de prix et ventes détectés automatiquement. Un véhicule qui disparaît | |
| 48 | −> du site source est marqué vendu dans Auto-Ka — et sa page renvoie alors un | |
| 49 | −> vrai `410 Gone` aux moteurs de recherche. | |
| 25 | +> Les sites de concessionnaires n'offrent pas de webhooks. Auto-Ka reproduit l'équivalent : **synchronisation périodique + hash de contenu** → **arrivages**, **baisses de prix** et **ventes** détectés automatiquement. Un véhicule qui disparaît du site source est **marqué vendu** — et sa page renvoie alors un vrai **`410 Gone`** aux moteurs de recherche. | |
| 50 | 26 | |
| 51 | −## Les chiffres | |
| 27 | +### Les chiffres | |
| 52 | 28 | |
| 53 | 29 | | Métrique | Valeur | |
| 54 | 30 | |---|---| |
| 55 | 31 | | Véhicules en vente | **17 698** — 17 082 autos · 591 motos · 25 scooters | |
| 56 | 32 | | Concessionnaires connectés | **138** (125 autos + 13 motos/scooters) | |
| 57 | −| Régions administratives couvertes | **18** · **72 villes** · **83 marques** | | |
| 33 | +| Couverture | **18 régions** · **72 villes** · **83 marques** | | |
| 58 | 34 | | 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 %** | | |
| 35 | +| Kilométrage / VIN | **99,7 %** / **95,1 %** | | |
| 61 | 36 | | Photos par véhicule (moyenne) | **~16** (galeries complètes) | |
| 62 | 37 | | Prix moyen / médian du parc | **28 529 $** / **24 995 $** | |
| 63 | 38 | | URLs indexables (SEO) | **18 475** — 17 698 fiches + 777 pages de recherche | |
| 64 | −| Cycle de rafraîchissement | **2 h** (PM2 watcher + enrichissement progressif) | | |
| 65 | − | |
| 66 | −## La fiche véhicule | |
| 39 | +| Cycle de rafraîchissement | **2 h** (watcher PM2 + enrichissement progressif) | | |
| 67 | 40 | |
| 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. | |
| 41 | +## Fonctionnalités | |
| 71 | 42 | |
| 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 | |
| 43 | +- **Recherche unifiée** — filtres **marque / modèle / année / prix / km / carburant / motricité / carrosserie / région / ville / concessionnaire**, avec facettes dynamiques et tri. | |
| 44 | +- **Fiches véhicule complètes** — galerie photos, caractéristiques standardisées, **VIN**, équipements, **historique de prix**, véhicules similaires toutes sources confondues, et **lien direct vers l'annonce originale** du concessionnaire, toujours. | |
| 45 | +- **Trois verticales, un moteur** — le champ `kind` (**`auto` / `moto` / `scooter`**) traverse tout le pipeline ; motos et scooters ont leurs onglets dédiés (13 concessionnaires **PowerGo**). | |
| 46 | +- **Suivi des baisses de prix** — le **diff engine** (upsert par hash de contenu) détecte nouveau / modifié / vendu, avec délai de grâce de 2 syncs et détection de dérive. | |
| 47 | +- **Statistiques du marché en direct** — tuiles de synthèse, distribution des prix, répartitions par région / marque / carrosserie, baisses récentes, et **rapport PDF** généré à la demande (`autoka/pdfgen.py`). | |
| 48 | +- **SEO programmatique massif** — la SPA React est servie avec un **rendu serveur complet** (`autoka/seo.py`) : title/meta uniques, canonical, Open Graph, hreflang `fr-CA`, **JSON-LD `Car`/`Motorcycle` + `Offer` + `BreadcrumbList`**, **~900 pages programmatiques** (`/usagees/{marque}`, `/usagees/{marque}/{modele}`, `/region/…`, `/ville/…`, `/carrosserie/…`, `/motos/…`), **sitemaps dynamiques** (18 475 URLs, `lastmod` réels), vendu → **410**, inconnu → **404**. | |
| 49 | +- **Compte KA ID** — SSO **« Se connecter avec KA ID »** via le hub [groupe-ka.com](https://www.groupe-ka.com) : même compte sur toutes les plateformes du groupe, page **/profil**, **favoris ♥ « Mon univers Ka »** centralisés. | |
| 50 | +- **Connecteurs auto-découvrants** — ajouter un concessionnaire = **~6 lignes** : une sous-classe de `BaseConnector` avec un `source_id` déposée dans `autoka/connectors/`, c'est tout. | |
| 77 | 51 | |
| 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> | |
| 52 | +### Principes | |
| 85 | 53 | |
| 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 | − | |
| 96 | −## L'architecture en 30 secondes | |
| 97 | − | |
| 98 | −```mermaid | |
| 99 | −flowchart LR | |
| 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…"] | |
| 102 | − end | |
| 103 | − subgraph AutoKa["Auto-Ka"] | |
| 104 | − C["Connecteurs<br/><i>1 adaptateur / plateforme</i>"] --> N["Normalisation<br/><i>schéma Vehicle unique</i>"] | |
| 105 | − N --> D[("SQLite<br/>hash + diff + prix")] | |
| 106 | − D --> A["API FastAPI<br/>/api/vehicles · /api/facets"] | |
| 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 | |
| 110 | − end | |
| 111 | − W["⏱ Watcher 2 h<br/>(PM2)"] -.-> C | |
| 112 | − S1 --> C | |
| 113 | − F --> U["🔑 Acheteur"] | |
| 114 | − SEO --> G["🕷 Googlebot"] | |
| 115 | −``` | |
| 116 | − | |
| 117 | −| Couche | Rôle | Fichiers | | |
| 118 | −|---|---|---| | |
| 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` | | |
| 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` | | |
| 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` | | |
| 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/` | | |
| 127 | − | |
| 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. | |
| 135 | − | |
| 136 | −<div align="center"> | |
| 137 | −<img src="docs/screenshot-seo-marque.png" alt="Auto-Ka — page programmatique Toyota usagées à vendre au Québec" width="920" /> | |
| 138 | −</div> | |
| 54 | +1. **À la source** — les annonces viennent des sites des concessionnaires eux-mêmes, jamais des plateformes d'agrégation existantes. | |
| 55 | +2. **Politesse** — délai ≥ 1 s entre requêtes, cache des pages détail, backoff sur rate-limit, User-Agent identifié. | |
| 56 | +3. **Fidélité** — **aucun prix inventé** : si la source n'affiche pas de prix, `price = null` (« Prix sur demande »). | |
| 57 | +4. **Traçabilité** — chaque fiche renvoie vers l'annonce originale. | |
| 58 | +5. **Robustesse** — un connecteur qui casse n'affecte jamais les autres ; détection de dérive (chute de volume → retraits suspendus + alerte). | |
| 59 | +6. **Honnêteté envers les moteurs** — le HTML servi aux robots est le même que celui servi aux humains. | |
| 139 | 60 | |
| 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) : | |
| 61 | +## Stack technique | |
| 142 | 62 | |
| 143 | −| Gabarit d'URL | Exemple | Contenu | | |
| 63 | +| Couche | Technologie | Rôle | | |
| 144 | 64 | |---|---|---| |
| 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). | |
| 65 | +| **Backend** | **Python 3.14** · **FastAPI** · **Uvicorn** | API `/api/*` + rendu serveur SEO + service du frontend | | |
| 66 | +| **Base de données** | **SQLite** | Diff engine : hash de contenu, historique de prix, cycle de vie des annonces | | |
| 67 | +| **Connecteurs** | requests · BeautifulSoup · Firecrawl/Scrapfly (sites derrière Cloudflare) | **1 adaptateur par plateforme** : D2C Media ×50, SM360 ×8, AMVOQ ×6, EvalAuto ×11, Convertus ×4, PowerGo ×13, HGrégoire, AED, customs… | | |
| 68 | +| **Frontend** | **React 18** · **Vite** · **TypeScript** | Design « éditorial sharp », accent orange racing — filtres, fiches, stats | | |
| 69 | +| **PDF** | reportlab · fpdf2 (`autoka/pdfgen.py`, `kapdf.py`) | Rapport « Le marché de l'occasion » | | |
| 70 | +| **Production** | **PM2** · **ngrok** | 3 processus résilients + tunnel www.auto-ka.com | | |
| 158 | 71 | |
| 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. | |
| 72 | +## Structure du projet | |
| 163 | 73 | |
| 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 | |
| 74 | +``` | |
| 75 | +auto-ka/ | |
| 76 | +├── run.py # Point d'entrée : sync | watch | serve | |
| 77 | +├── requirements.txt # Dépendances backend | |
| 78 | +├── autoka/ | |
| 79 | +│ ├── connectors/ # 1 module par plateforme, 1 sous-classe par concessionnaire | |
| 80 | +│ ├── schema.py # Schéma Vehicle standardisé (kind: auto/moto/scooter) | |
| 81 | +│ ├── normalize.py # Prix/km/année, marques canoniques, ville → région | |
| 82 | +│ ├── ingest.py # Pipeline d'ingestion | |
| 83 | +│ ├── db.py # SQLite — diff engine, hash, historique de prix | |
| 84 | +│ ├── web.py # API FastAPI (/api/vehicles, /api/facets, /api/stats…) | |
| 85 | +│ ├── seo.py # Rendu serveur SEO : HTML complet, JSON-LD, sitemaps, 410/404 | |
| 86 | +│ ├── auth.py # SSO KA ID (hub groupe-ka.com) | |
| 87 | +│ ├── hubprofile.py # Profil Groupe KA | |
| 88 | +│ ├── hubfav.py # Favoris « Mon univers Ka » | |
| 89 | +│ ├── marketstats.py # Statistiques du marché | |
| 90 | +│ ├── statsdash.py # Tableau de bord analytique | |
| 91 | +│ └── pdfgen.py · kapdf.py# Rapport PDF | |
| 92 | +├── frontend/ # React 18 + Vite + TypeScript (build → dist/) | |
| 93 | +├── data/ # sources.json (registre des concessionnaires) + base | |
| 94 | +└── docs/ # Captures d'écran | |
| 167 | 95 | ``` |
| 168 | 96 | |
| 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 | − | |
| 178 | −## Démarrage rapide | |
| 97 | +## Démarrage local | |
| 179 | 98 | |
| 180 | 99 | ```bash |
| 181 | 100 | git clone https://git.spboucher.ai/auto-ka.git && cd auto-ka |
@@ -190,17 +109,12 @@ cd frontend && npm install && npm run build && cd .. | ||
| 190 | 109 | echo "FIRECRAWL_API_KEY=fc-votre-cle" > .env |
| 191 | 110 | |
| 192 | 111 | # Ingestion puis service |
| 193 | −.venv/bin/python run.py sync # toutes les sources (ou: run.py sync forceoccasion) | |
| 112 | +.venv/bin/python run.py sync # toutes les sources (ou : run.py sync forceoccasion) | |
| 194 | 113 | .venv/bin/python run.py serve 8080 # → http://localhost:8080 |
| 195 | 114 | .venv/bin/python run.py watch 120 # resynchronisation en boucle (minutes) |
| 196 | 115 | ``` |
| 197 | 116 | |
| 198 | −## Ajouter un concessionnaire (≈ 6 lignes) | |
| 199 | − | |
| 200 | −L'enregistrement est **auto-découvrant** : déposez un module dans | |
| 201 | −`autoka/connectors/` contenant une sous-classe de `BaseConnector` avec un | |
| 202 | −`source_id` — c'est tout. Pour un site D2C Media (le fournisseur le plus | |
| 203 | −répandu au Québec) : | |
| 117 | +### Ajouter un concessionnaire (≈ 6 lignes) | |
| 204 | 118 | |
| 205 | 119 | ```python |
| 206 | 120 | # dans autoka/connectors/d2c_dealers.py |
@@ -211,12 +125,9 @@ class MonConcessionnaire(D2CConnector): | ||
| 211 | 125 | city = "Sherbrooke" |
| 212 | 126 | ``` |
| 213 | 127 | |
| 214 | −Puis : `.venv/bin/python run.py sync monconcessionnaire` — et l'inventaire | |
| 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**. | |
| 128 | +Puis `.venv/bin/python run.py sync monconcessionnaire` — l'inventaire apparaît sur le site avec fiches, galeries, liens sources… et dans le sitemap. Ajouter l'entrée correspondante dans `data/sources.json` pour la page **Sources**. | |
| 218 | 129 | |
| 219 | −## API | |
| 130 | +### API | |
| 220 | 131 | |
| 221 | 132 | | Endpoint | Description | |
| 222 | 133 | |---|---| |
@@ -230,73 +141,43 @@ Ajoutez l'entrée correspondante dans `data/sources.json` pour la page | ||
| 230 | 141 | | `GET /api/auth/ka/login` · `/api/favorites` | SSO KA ID + favoris hub | |
| 231 | 142 | | `GET /robots.txt` · `/sitemap.xml` | SEO — sitemaps dynamiques avec lastmod | |
| 232 | 143 | |
| 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> | |
| 238 | − | |
| 239 | −## Couverture | |
| 240 | − | |
| 241 | −**Grands réseaux** — HGrégoire (mégacentres partout au Québec), Automobile En | |
| 242 | −Direct, Occasion Beaucage (7 concessions), Le Prix du Gros, Méga Centre de | |
| 243 | −liquidation, St-Jérôme Auto Dépôt, Ste-Foy Chrysler, Desmeules, Entrepôt Auto | |
| 244 | −Durocher… **Motos & scooters** — Motos Illimitées, concessionnaires | |
| 245 | −Harley-Davidson, Honda, Yamaha, Kawasaki, BMW, Vespa via PowerGo. | |
| 144 | +## Déploiement | |
| 246 | 145 | |
| 247 | −**Toutes les régions** — Montérégie, Capitale-Nationale, Laurentides, Mauricie, | |
| 248 | −Laval, Estrie, Outaouais, Centre-du-Québec, Chaudière-Appalaches, Lanaudière, | |
| 249 | −Montréal, Saguenay–Lac-Saint-Jean, Bas-Saint-Laurent, Abitibi-Témiscamingue, | |
| 250 | −Côte-Nord, Gaspésie… | |
| 146 | +L'application tourne en production sur le **nœud M4M64b** du cluster MacLustr, sur le **port 8095**, exposée publiquement via **ngrok** sur **[www.auto-ka.com](https://www.auto-ka.com)**. | |
| 251 | 147 | |
| 252 | −Chaque source non connectable est **documentée avec sa raison** dans | |
| 253 | −`data/sources.json` (ex. : doublon d'inventaire d'un autre site du même | |
| 254 | −groupe, vérifié par VIN). | |
| 148 | +Trois processus **PM2** : | |
| 255 | 149 | |
| 256 | −## Production | |
| 150 | +| Processus PM2 | Commande | Rôle | | |
| 151 | +|---|---|---| | |
| 152 | +| **`auto-ka-web`** | `.venv/bin/python run.py serve 8095` | **API + frontend + SSR SEO** | | |
| 153 | +| **`auto-ka-sync`** | `.venv/bin/python run.py watch 120` | **Resynchronisation toutes les 2 h** | | |
| 154 | +| **`auto-ka-ngrok`** | `ngrok http --url=www.auto-ka.com 8095` | **Tunnel public** | | |
| 257 | 155 | |
| 258 | −Déployé sous **PM2** (3 processus) derrière **ngrok** : | |
| 156 | +Philosophie d'exploitation : **on ne pousse que le code — le serveur maintient ses données lui-même.** | |
| 259 | 157 | |
| 260 | −``` | |
| 261 | −auto-ka-web .venv/bin/python run.py serve 8095 # API + frontend + SSR SEO | |
| 262 | −auto-ka-sync .venv/bin/python run.py watch 120 # resync 2 h | |
| 263 | −auto-ka-ngrok ngrok http --url=www.auto-ka.com 8095 # tunnel | |
| 264 | −``` | |
| 158 | +## Développement remote-first (IMPORTANT) | |
| 265 | 159 | |
| 266 | −Philosophie d'exploitation : **on ne pousse que le code — le serveur maintient | |
| 267 | −ses données lui-même.** | |
| 160 | +- La **source de vérité** est le **repo git sur le nœud M4M64b** (`~/auto-ka`) — **il n'existe aucune copie laptop**. | |
| 161 | +- Toute modification se fait **sur le nœud via SSH** : édition, build, `pm2 restart`, puis `git add / commit / push` **depuis le nœud** (agent forwarding actif). | |
| 162 | +- Le remote **`origin` = spbgit** (git perso **[git.spboucher.ai](https://git.spboucher.ai)**), via l'**alias SSH `gitsrv`** → `gitsrv:srv/git/auto-ka.git`. **Pas GitHub.** | |
| 268 | 163 | |
| 269 | −## Principes | |
| 164 | +## Captures supplémentaires | |
| 270 | 165 | |
| 271 | −1. **À la source** — les annonces viennent des sites des concessionnaires | |
| 272 | − eux-mêmes, jamais des plateformes d'agrégation existantes. | |
| 273 | −2. **Politesse** — délai ≥ 1 s entre requêtes, cache des pages détail | |
| 274 | − (revalidation hebdomadaire), backoff sur rate-limit, User-Agent identifié. | |
| 275 | −3. **Fidélité** — aucun prix inventé : si la source n'affiche pas de prix, | |
| 276 | − `price = null` (« Prix sur demande »). | |
| 277 | −4. **Traçabilité** — chaque fiche renvoie vers l'annonce originale. | |
| 278 | −5. **Robustesse** — un connecteur qui casse n'affecte jamais les autres ; | |
| 279 | − un 404 (véhicule vendu) ne bloque jamais une source ; détection de dérive | |
| 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. | |
| 166 | +| | | | |
| 167 | +|---|---| | |
| 168 | +| Fiche véhicule |  | | |
| 169 | +| Statistiques du marché |  | | |
| 170 | +| Verticale motos |  | | |
| 171 | +| Page programmatique SEO |  | | |
| 284 | 172 | |
| 285 | 173 | --- |
| 286 | 174 | |
| 287 | 175 | <div align="center"> |
| 288 | 176 | |
| 289 | −## Auteur | |
| 290 | − | |
| 291 | −**Simon-Pierre Boucher** | |
| 292 | − | |
| 293 | −[](mailto:contact@spboucher.ai) | |
| 294 | −[](https://git.spboucher.ai) | |
| 295 | − | |
| 296 | −*Conçu, construit et déployé en une journée — du sondage de plateformes | |
| 297 | −(60+ sites classifiés) aux 138 connecteurs, trois verticales et 18 475 pages | |
| 298 | −indexables en production.* | |
| 177 | +**Simon-Pierre Boucher** — [contact@spboucher.ai](mailto:contact@spboucher.ai) · [git.spboucher.ai](https://git.spboucher.ai) | |
| 299 | 178 | |
| 300 | 179 | © 2026 Simon-Pierre Boucher — tous droits réservés. |
| 301 | 180 | |
| 181 | +Un service **Groupe Ka** | |
| 182 | + | |
| 302 | 183 | </div> |
added
docs/screenshot.png
+0 −0
Binary file not shown.