# Auto·Ka
### Toutes les voitures usagées à vendre au Québec. Un seul endroit.
**[www.auto-ka.com](https://www.auto-ka.com)**










*Agrégateur indépendant de voitures usagées — chaque annonce avec ses photos,
ses caractéristiques standardisées (année, km, transmission, carburant, VIN…)
et un lien direct vers l'annonce originale du concessionnaire. Toujours à
jour, automatiquement. Suivi des baisses de prix intégré.*
---
## Pourquoi Auto-Ka ?
Chercher une auto usagée au Québec, c'est 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.
> 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 dans Auto-Ka.
## Les chiffres
| Métrique | Valeur |
|---|---|
| Véhicules en vente | **13 713** |
| Concessionnaires connectés | **99** (95+ connecteurs actifs) |
| Régions administratives couvertes | **18 / 17** (+ Outaouais frontalier) |
| Annonces avec prix affiché | **100 %** (jamais de prix inventé) |
| Annonces avec kilométrage | **99,9 %** |
| Annonces avec photos | **~99 %** |
| Prix moyen du marché | **28 181 $** |
| Cycle de rafraîchissement | **2 h** (PM2 watcher) |
## L'architecture en 30 secondes
```mermaid
flowchart LR
subgraph Sources["99 concessionnaires"]
S1["D2C Media ×50 · SM360 ×8
AMVOQ ×6 · EvalAuto ×11
Convertus ×4 · customs
HGrégoire · AED · Beaucage…"]
end
subgraph AutoKa["Auto-Ka"]
C["Connecteurs
1 adaptateur / plateforme"] --> N["Normalisation
schéma Vehicle unique"]
N --> D[("SQLite
hash + diff + prix")]
D --> A["API FastAPI
/api/vehicles · /api/facets"]
A --> F["React 18 + Vite
filtres auto · fiches · stats"]
end
W["⏱ Watcher 2 h
(PM2)"] -.-> C
S1 --> C
F --> U["🔑 Acheteur"]
```
| Couche | Rôle | Fichiers |
|---|---|---|
| **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` |
| **Schéma** | `Vehicle` standardisé : marque, modèle, année, prix, km, transmission, carburant, motricité, carrosserie, couleurs, VIN, photos, région | `autoka/schema.py` |
| **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` |
| **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` |
| **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` |
| **Frontend** | Design « éditorial sharp », accent orange racing : filtres auto complets, fiches avec galerie photos, historique de prix et véhicules similaires | `frontend/` |
## Le marché en direct
## Démarrage rapide
```bash
git clone https://git.spboucher.ai/auto-ka.git && cd auto-ka
# Backend
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
# Frontend
cd frontend && npm install && npm run build && cd ..
# Sites derrière Cloudflare (optionnel)
echo "FIRECRAWL_API_KEY=fc-votre-cle" > .env
# Ingestion puis service
.venv/bin/python run.py sync # toutes les sources (ou: run.py sync forceoccasion)
.venv/bin/python run.py serve 8080 # → http://localhost:8080
.venv/bin/python run.py watch 120 # resynchronisation en boucle (minutes)
```
## Ajouter un concessionnaire (≈ 6 lignes)
L'enregistrement est **auto-découvrant** : déposez un module dans
`autoka/connectors/` contenant une sous-classe de `BaseConnector` avec un
`source_id` — c'est tout. Pour un site D2C Media (le fournisseur le plus
répandu au Québec) :
```python
# dans autoka/connectors/d2c_dealers.py
class MonConcessionnaire(D2CConnector):
source_id = "monconcessionnaire"
base_url = "https://www.monconcessionnaire.ca"
dealer_name = "Mon Concessionnaire"
city = "Sherbrooke"
```
Puis : `.venv/bin/python run.py sync monconcessionnaire` — et l'inventaire
apparaît sur le site avec fiches, galeries et liens sources. Ajoutez l'entrée
correspondante dans `data/sources.json` pour la page **Sources**.
## API
| Endpoint | Description |
|---|---|
| `GET /api/vehicles?make=&model=®ion=&price_max=&km_max=&fuel=&sort=` | Recherche filtrée et triée |
| `GET /api/vehicles/{uid}` | Fiche complète (photos, historique de prix, similaires) |
| `GET /api/facets?make=` | Valeurs distinctes pour construire les filtres |
| `GET /api/sources` | Registre des concessionnaires + compteurs + dernière sync |
| `GET /api/stats` | Totaux, moyennes, top marques/régions, baisses de prix récentes |
| `POST /api/sync` | Déclenche une synchronisation en arrière-plan |
## Couverture
**Grands réseaux** — HGrégoire (mégacentres partout au Québec), Automobile En
Direct, Occasion Beaucage (7 concessions), Le Prix du Gros, Méga Centre de
liquidation, St-Jérôme Auto Dépôt, Ste-Foy Chrysler, Desmeules, Entrepôt Auto
Durocher…
**Toutes les régions** — Montérégie, Capitale-Nationale, Laurentides, Mauricie,
Laval, Estrie, Outaouais, Centre-du-Québec, Chaudière-Appalaches, Lanaudière,
Montréal, Saguenay–Lac-Saint-Jean, Bas-Saint-Laurent, Abitibi-Témiscamingue,
Côte-Nord, Gaspésie…
Chaque source non connectable est **documentée avec sa raison** dans
`data/sources.json` (ex. : doublon d'inventaire d'un autre site du même
groupe, vérifié par VIN).
## Production
Déployé sous **PM2** (3 processus) derrière **ngrok** :
```
auto-ka-web .venv/bin/python run.py serve 8095 # API + frontend
auto-ka-sync .venv/bin/python run.py watch 120 # resync 2 h
auto-ka-ngrok ngrok http --url=www.auto-ka.com 8095 # tunnel
```
Philosophie d'exploitation : **on ne pousse que le code — le serveur maintient
ses données lui-même.**
## Principes
1. **À la source** — les annonces viennent des sites des concessionnaires
eux-mêmes, jamais des plateformes d'agrégation existantes.
2. **Politesse** — délai ≥ 1 s entre requêtes, cache des pages détail
(revalidation hebdomadaire), backoff sur rate-limit, User-Agent identifié.
3. **Fidélité** — aucun prix inventé : si la source n'affiche pas de prix,
`price = null` (« Prix sur demande »).
4. **Traçabilité** — chaque fiche renvoie vers l'annonce originale.
5. **Robustesse** — un connecteur qui casse n'affecte jamais les autres ;
un 404 (véhicule vendu) ne bloque jamais une source ; détection de dérive
(chute de volume → retraits suspendus + alerte).
---
## Auteur
**Simon-Pierre Boucher**
[](mailto:contact@spboucher.ai)
[](https://git.spboucher.ai)
*Conçu, construit et déployé en une journée — du sondage de plateformes
(60+ sites classifiés) aux 99 connecteurs en production.*
© 2026 Simon-Pierre Boucher — tous droits réservés.