spb/auto-ka Public
Python 82.3%
TypeScript 12%
CSS 5.4%
1<div align="center">23# Auto·Ka45### Toutes les voitures usagées à vendre au Québec. Un seul endroit.67**[www.auto-ka.com](https://www.auto-ka.com)**89101112131415161718192021*Agrégateur indépendant de voitures usagées — chaque annonce avec ses photos,22ses caractéristiques standardisées (année, km, transmission, carburant, VIN…)23et un lien direct vers l'annonce originale du concessionnaire. Toujours à24jour, automatiquement. Suivi des baisses de prix intégré.*2526<img src="docs/screenshot-home.png" alt="Auto-Ka — recherche de véhicules" width="920" />2728</div>2930---3132## Pourquoi Auto-Ka ?3334Chercher une auto usagée au Québec, c'est ouvrir des dizaines de sites de35concessionnaires — chacun avec sa navigation, ses filtres, son format.36**Auto-Ka retourne le problème** : un connecteur dédié par commerce visite37chaque site **à la source** (aucune plateforme d'annonces revendue), normalise38chaque véhicule vers un schéma unique et détecte les changements en continu.3940> Les sites de concessionnaires n'offrent pas de webhooks. Auto-Ka reproduit41> l'équivalent : **synchronisation périodique + hash de contenu** → arrivages,42> baisses de prix et ventes détectés automatiquement. Un véhicule qui disparaît43> du site source est marqué vendu dans Auto-Ka.4445## Les chiffres4647| Métrique | Valeur |48|---|---|49| Véhicules en vente | **13 713** |50| Concessionnaires connectés | **99** (95+ connecteurs actifs) |51| Régions administratives couvertes | **18 / 17** (+ Outaouais frontalier) |52| Annonces avec prix affiché | **100 %** (jamais de prix inventé) |53| Annonces avec kilométrage | **99,9 %** |54| Annonces avec photos | **~99 %** |55| Prix moyen du marché | **28 181 $** |56| Cycle de rafraîchissement | **2 h** (PM2 watcher) |5758## L'architecture en 30 secondes5960```mermaid61flowchart LR62 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…"]64 end65 subgraph AutoKa["Auto-Ka"]66 C["Connecteurs<br/><i>1 adaptateur / plateforme</i>"] --> N["Normalisation<br/><i>schéma Vehicle unique</i>"]67 N --> D[("SQLite<br/>hash + diff + prix")]68 D --> A["API FastAPI<br/>/api/vehicles · /api/facets"]69 A --> F["React 18 + Vite<br/>filtres auto · fiches · stats"]70 end71 W["⏱ Watcher 2 h<br/>(PM2)"] -.-> C72 S1 --> C73 F --> U["🔑 Acheteur"]74```7576| Couche | Rôle | Fichiers |77|---|---|---|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` |80| **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| **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/` |8485## Le marché en direct8687<div align="center">88<img src="docs/screenshot-stats.png" alt="Auto-Ka — statistiques du marché et baisses de prix" width="920" />89</div>9091## Démarrage rapide9293```bash94git clone https://git.spboucher.ai/auto-ka.git && cd auto-ka9596# Backend97python3 -m venv .venv && .venv/bin/pip install -r requirements.txt9899# Frontend100cd frontend && npm install && npm run build && cd ..101102# Sites derrière Cloudflare (optionnel)103echo "FIRECRAWL_API_KEY=fc-votre-cle" > .env104105# Ingestion puis service106.venv/bin/python run.py sync # toutes les sources (ou: run.py sync forceoccasion)107.venv/bin/python run.py serve 8080 # → http://localhost:8080108.venv/bin/python run.py watch 120 # resynchronisation en boucle (minutes)109```110111## Ajouter un concessionnaire (≈ 6 lignes)112113L'enregistrement est **auto-découvrant** : déposez un module dans114`autoka/connectors/` contenant une sous-classe de `BaseConnector` avec un115`source_id` — c'est tout. Pour un site D2C Media (le fournisseur le plus116répandu au Québec) :117118```python119# dans autoka/connectors/d2c_dealers.py120class MonConcessionnaire(D2CConnector):121 source_id = "monconcessionnaire"122 base_url = "https://www.monconcessionnaire.ca"123 dealer_name = "Mon Concessionnaire"124 city = "Sherbrooke"125```126127Puis : `.venv/bin/python run.py sync monconcessionnaire` — et l'inventaire128apparaît sur le site avec fiches, galeries et liens sources. Ajoutez l'entrée129correspondante dans `data/sources.json` pour la page **Sources**.130131## API132133| Endpoint | Description |134|---|---|135| `GET /api/vehicles?make=&model=®ion=&price_max=&km_max=&fuel=&sort=` | Recherche filtrée et triée |136| `GET /api/vehicles/{uid}` | Fiche complète (photos, historique de prix, similaires) |137| `GET /api/facets?make=` | Valeurs distinctes pour construire les filtres |138| `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 |140| `POST /api/sync` | Déclenche une synchronisation en arrière-plan |141142## Couverture143144**Grands réseaux** — HGrégoire (mégacentres partout au Québec), Automobile En145Direct, Occasion Beaucage (7 concessions), Le Prix du Gros, Méga Centre de146liquidation, St-Jérôme Auto Dépôt, Ste-Foy Chrysler, Desmeules, Entrepôt Auto147Durocher…148149**Toutes les régions** — Montérégie, Capitale-Nationale, Laurentides, Mauricie,150Laval, Estrie, Outaouais, Centre-du-Québec, Chaudière-Appalaches, Lanaudière,151Montréal, Saguenay–Lac-Saint-Jean, Bas-Saint-Laurent, Abitibi-Témiscamingue,152Côte-Nord, Gaspésie…153154Chaque source non connectable est **documentée avec sa raison** dans155`data/sources.json` (ex. : doublon d'inventaire d'un autre site du même156groupe, vérifié par VIN).157158## Production159160Déployé sous **PM2** (3 processus) derrière **ngrok** :161162```163auto-ka-web .venv/bin/python run.py serve 8095 # API + frontend164auto-ka-sync .venv/bin/python run.py watch 120 # resync 2 h165auto-ka-ngrok ngrok http --url=www.auto-ka.com 8095 # tunnel166```167168Philosophie d'exploitation : **on ne pousse que le code — le serveur maintient169ses données lui-même.**170171## Principes1721731. **À la source** — les annonces viennent des sites des concessionnaires174 eux-mêmes, jamais des plateformes d'agrégation existantes.1752. **Politesse** — délai ≥ 1 s entre requêtes, cache des pages détail176 (revalidation hebdomadaire), backoff sur rate-limit, User-Agent identifié.1773. **Fidélité** — aucun prix inventé : si la source n'affiche pas de prix,178 `price = null` (« Prix sur demande »).1794. **Traçabilité** — chaque fiche renvoie vers l'annonce originale.1805. **Robustesse** — un connecteur qui casse n'affecte jamais les autres ;181 un 404 (véhicule vendu) ne bloque jamais une source ; détection de dérive182 (chute de volume → retraits suspendus + alerte).183184---185186<div align="center">187188## Auteur189190**Simon-Pierre Boucher**191192[](mailto:contact@spboucher.ai)193[](https://git.spboucher.ai)194195*Conçu, construit et déployé en une journée — du sondage de plateformes196(60+ sites classifiés) aux 99 connecteurs en production.*197198© 2026 Simon-Pierre Boucher — tous droits réservés.199200</div>201