SPB Git

spb/resto-ka

Public

Resto·Ka — tous les restaurants du Québec, menus complets et prix réels (famille ·Ka)

20.8 KB

Resto·Ka — Chaque resto, chaque plat, chaque prix

Resto·Ka

Chaque resto, chaque plat, chaque prix

Site Santé API (live) Documentation PDF Nœud Port PM2

Restaurants (live) Plats avec prix (live) Menus capturés (live) Chaînes (live) Régions (live) Inspections MAPAQ (live) Permis d'alcool (live) Sources au registre (live)
Python FastAPI React Vite SQLite PM2 ngrok Groupe KA remote-first spbgit

Resto·Ka (www.resto-ka.com) est l'agrégateur exhaustif des restaurants du Québec : chaque resto, chaque plat, chaque prix — dans les 17 régions administratives, au même endroit, comparable et cherchable par resto ou par plat. Les prix sont des prix takeout réels, non majorés, captés sur la plateforme de commande des restos eux-mêmes (pas sur les apps de livraison, majorées de 25-30 %).

En chiffres (live /api/stats, au 2026-08-24) : 14 716 restaurants actifs (hors doublons, découverte OpenStreetMap, 17/17 régions), 149 569 plats avec prix, 1 682 menus capturés (1 268 takeout · 386 salle · 31 livraison), 180 chaînes identifiées dont 116 intégrations UEAT découvertes, 2 994 inspections MAPAQ importées, 1 859 restos avec permis d'alcool (RACJ), 155 312 entrées d'historique de prix, 80 % des items avec photo, 100 % des restos géolocalisés. Pour qui ? Quiconque veut répondre à « qu'est-ce que je mange, où, et combien ça coûte ? » sans ouvrir quinze applis — là où les apps de livraison majorent et où les annuaires (Google, Yelp) n'ont ni menus structurés ni prix comparables.

# Visite guidée


Accueil — recherche par resto ou par plat (desktop)

Accueil — version mobile

Étape 1 · Cherchez un resto ou un plat depuis l'accueil

Étape 2 · Parcourez les restos d'une ville

Étape 3 · Ouvrez la fiche d'un restaurant

Étape 4 · Comparez le marché sur /stats

Accueil — variante pleine page

Fiche restaurant — menu structuré et prix contextualisés

Recherche par plat — 149 569 items, groupés par marque

Tableau de bord /stats — le marché resto en chiffres

# Fonctionnalités

  • Prix réels et contextualisés — un prix n'est jamais présenté sans son contexte (dine-in / takeout / delivery) ; un menu sans price_context/price_source est rejeté à l'ingestion, et un menu salle n'est jamais écrasé par un menu livraison.
  • Recherche par plat dans les 149 569 items (au 2026-08-24), groupée par marque (pour ne pas répéter la même poutine de chaîne des dizaines de fois).
  • Options & formats capturés avec leurs suppléments (« Mini +3,70 $ ») — ils changent le prix réel.
  • Historique des prix par item (item_price_log, 155 312 entrées au 2026-08-24) à chaque changement.
  • Alerte de dérive — chute anormale du volume d'une source ou du nombre d'items d'un menu → retraits suspendus / ancien menu conservé.
  • Déduplication inter-sources (les succursales ne sont jamais fusionnées) et géocodage à 100 % (Nominatim + Adresses Québec, cache persistant).
  • Découverte OpenStreetMap (API Overpass) : 13 427 établissements nommés au dernier passage — restos, fast-foods, cafés, bars, crèmeries, boulangeries — dans les 17 régions ; connecteur UEAT templatisé (API GraphQL) pour les menus takeout réels de 116 intégrations de chaînes découvertes (Sushi Shop, Valentine, Normandin, Thaïzone, Chez Ashton…).
  • Découverte des sites web des restos OSM (connecteur site-finder, Serper /maps) et extraction des photos depuis les sites des restos (site-resto).
  • Enrichissements officiels : inspections MAPAQ (2 994 importées, 288 appariées à 204 restos) et permis d'alcool RACJ (1 859 restos).
  • Avis & notes : Yelp par scraping quotidien (177 restos notés) et croisement Uber Eats (36 restos, prix marqués delivery).
  • Connexion KA ID (SSO Groupe KA), favoris unifiés « Mon univers Ka », tableau de bord /stats + rapports PDF (catalogue + ReportBuilder), widget KA Agent (chat IA).
  • Registre des sources — data/sources.json (10 sources), à consulter avant tout ajout (statut et raison des sources non connectables).

# Démarrage rapide

bash
# Backend
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt

# Frontend (build servi par FastAPI)
cd frontend && npm install && npm run build && cd ..
# ou en dev : cd frontend && npm run dev

# Lancer
.venv/bin/python run.py sync            # synchronise (+ géocode + dédup)
.venv/bin/python run.py serve 8115      # API + frontend sur :8115
.venv/bin/python run.py watch 168       # boucle hebdomadaire (heures)

# Tests (80 tests pytest, fixtures réelles hors ligne)
.venv/bin/python -m pytest tests/

# API (endpoints)

Servis par restoka/web.py (FastAPI) sur le port 8115.

Méthode Endpoint Description
GET /api/restaurants recherche de restos (ville, région, cuisine, texte libre, uids=, pagination)
GET /api/restaurants/{uid} fiche complète : menu structuré par contexte de prix, photos, coordonnées, horaires
GET /api/restaurants/{uid}/prices historique des prix des items du resto (item_price_log)
GET /api/restaurants/{uid}/inspections inspections/permis (enrichissements MAPAQ + RACJ)
GET /api/dishes recherche par plat dans les 149 569 items, groupée par marque
GET /api/facets facettes de filtres (régions, villes, cuisines, types)
GET /api/sources registre des sources (statuts, cadences)
GET /api/stats statistiques publiques JSON (alimente les pastilles ci-dessus)
GET /api/stats/dashboard données du tableau de bord /stats
GET /api/stats/report rapport PDF principal
GET /api/stats/catalog catalogue des rapports disponibles
POST /api/stats/report/custom rapport PDF personnalisé (ReportBuilder)
GET /api/favorites favoris « Mon univers Ka » (session KA ID)
POST /api/favorites/toggle ajout/retrait d'un favori
POST /api/sync déclenchement d'une synchronisation
GET /healthz santé du service ({"status":"ok"})
GET /doc/ guide d'utilisation en ligne
GET /{full_path} SPA + pages SSR légères (accueil, fiches JSON-LD, /villes)

# Connecteurs

Auto-enregistrés dans restoka/connectors/ (requests direct / Firecrawl / Scrapfly + cache détail dans base.py, résilience _resilient.py, chaîne anti-bot Oxylabs → Scrapfly → Bright Data) :

Connecteur Famille Rôle Cadence
osm découverte OpenStreetMap (Overpass, miroirs fiabilisés) — 13 427 établissements nommés, 17/17 régions mensuelle
ueat menus takeout (tier 1) connecteur templatisé UEAT (API GraphQL) — menus takeout réels de 116 intégrations découvertes hebdomadaire
siteresto menus salle menus + photos publiés sur le site des restos indépendants hebdo (batch incrémental), re-crawl mensuel
sitefinder découverte sites web / plateformes de commande des restos OSM (Serper /maps) hebdo par lots (3 000 req.), échecs re-sondés 180 j
ubereats livraison complément livraison (prix delivery, jamais prioritaires sur un menu salle) quotidienne par petits lots (60 pages), re-vérif 30 j
yelp annuaire enrichissement via l'API Yelp Fusion (clé requise — SkipSource sans YELP_API_KEY) hebdo, re-vérification 30 j
yelp_scrape annuaire notes, nombre d'avis, gamme de prix, catégories, fermetures via yelp.ca quotidienne par petits lots (80 pages), re-vérif 30 j

S'y ajoutent deux enrichissements officiels exécutés par ingest.enrich (garde-fou 6 jours) : mapaq (inspections) et racj (permis d'alcool), tous deux hebdomadaires.

# Données & conformité

  • Registre des sources : data/sources.json — 10 sources au 2026-08-24 (8 actives, 1 « clé requise » : yelp, 1 « à faire » : sthubert). À consulter avant tout ajout de source (CLAUDE.md §0.4) : chaque entrée documente l'accès légal, l'extraction et la cadence.
  • Prix de première partie : les menus takeout viennent de la plateforme de commande des restos eux-mêmes (UEAT — la même API GraphQL que le widget officiel, auth anonyme publique) ou de leur propre site — prix réels non majorés. Les menus salle (site-resto) et takeout passent toujours avant les plateformes de livraison.
  • Scraping poli : throttling (0,35 s sur UEAT), User-Agent identifiable RestoKaBot, budgets par passage (Yelp 450 req/j, site-finder 3 000 req, Uber Eats 60 pages/j).
  • Données publiques officielles : inspections MAPAQ et permis d'alcool RACJ (jeux de données gouvernementaux).
  • Cadence de resync : boucle run.py watch 168 (cycle hebdomadaire) ; les sources quotidiennes (yelp-scrape, ubereats) avancent par petits lots à chaque passage ; alertes de dérive + délai de grâce avant tout retrait.
  • La base SQLite de prod (data/restoka.db) est gitignorée ; aucun secret dans le repo (.env local, gabarit .env.example).

# Architecture

Pipeline (patron Lou·Ka) : connecteurs → normalisation → déduplication → SQLite → API/frontend.

  • Backend Python 3.14 / FastAPI / Uvicorn (restoka/web.py) : API + service du build Vite + SSR léger SEO (JSON-LD Restaurant, sitemaps chunkés, pages /villes).
  • SQLite (restoka/db.py) : restos, menus par contexte de prix, historique de prix (item_price_log), inspections, favoris, caches détail/géocodage.
  • Connecteurs auto-enregistrés (restoka/connectors/) : requests direct / Firecrawl / Scrapfly + cache détail (base.py), UEAT templatisé (ueat.py), découverte Overpass/OSM.
  • Ingestion (restoka/ingest.py) : sync → geocode → dedup, délai de grâce et alertes de dérive ; enrichissements inspections/permis/heures.
  • Structuration LLM (restoka/menullm.py) : menus maison structurés par Claude (API Anthropic).
  • Frontend React 18 + Vite + TypeScript (frontend/), design « éditorial sharp » Groupe KA.
  • 80 tests pytest avec fixtures réelles hors ligne (connecteurs, normalisation, schéma, horaires, permis…).

Processus PM2 sur le nœud (commandes de start réelles) :

Processus Rôle Commande Cadence
resto-ka serveur FastAPI (API + frontend) sur le port 8115 .venv/bin/python run.py serve 8115 continu
resto-ka-sync boucle de synchronisation .venv/bin/python run.py watch 168 cycle hebdomadaire (168 h)
resto-ka-ngrok tunnel vers www.resto-ka.com ngrok http --url=www.resto-ka.com 8115 continu

# Variables d'environnement

Gabarit : .env.example (copier vers .env, jamais commité). Noms seulement — aucune valeur dans le repo.

Variable Rôle
SCRAPFLY_KEY rendu JS + bypass anti-bot (plateformes de livraison)
ANTHROPIC_API_KEY structuration des menus maison par Claude (restoka/menullm.py)
FIRECRAWL_API_KEY rendu JS de secours pour les sites de restos SPA (site-resto)
YELP_API_KEY API Yelp Fusion (sans clé : source sautée proprement)
YELP_BUDGET budget de requêtes Yelp par passage (quota quotidien 500)
SERPER_API_KEY Google Maps via Serper — découverte des sites web (site-finder)
SITE_FINDER_BUDGET budget de requêtes Serper par passage (défaut 3 000)
KA_SSO_SECRET SSO Groupe KA (« Se connecter avec KA »)
SESSION_SECRET sessions signées
RESTOKA_BASE_URL URL publique du site (défaut https://www.resto-ka.com)

# Structure du repo

text
resto-ka/
├── run.py           # point d'entrée CLI (sync / watch / serve)
├── restoka/         # cœur Python : web, db, ingest, dedup, geocode, regions, schema, normalize, auth, stats, menullm… + connectors/
├── frontend/        # React 18 + Vite + TypeScript — design éditorial sharp Groupe KA + public/doc/ (guide)
├── data/            # sources.json (registre), ueat-discovered.json (116 intégrations), base SQLite de prod (gitignorée)
├── scripts/         # scripts d'appoint (captures, déploiement)
├── tests/           # 80 tests pytest (fixtures réelles hors ligne)
└── docs/            # captures d'écran + docs connecteurs

# Documentation

  • Guide en ligne : www.resto-ka.com/doc/ — à quoi sert le site, le parcours en 4 étapes (recherche → restos d'une ville → fiche → /stats), d'où viennent les données, FAQ.
  • Guide PDF : resto-ka-documentation.pdf — la même documentation, téléchargeable.
  • Les captures du guide sont versionnées dans frontend/public/doc/img/ (etape1 → etape4).

# Développement (remote-first)

La source de vérité est le repo git sur le nœud M3U96b (~/apps/resto-ka) — on n'édite jamais les copies laptop. Toute modification se fait sur le nœud via SSH : édition, build, pm2 restart, puis commit/push depuis le nœud.

  • Remote origin = spbgit (git perso git.spboucher.ai, bare repos sur M3U96a). Pas GitHub.
  • L'agent forwarding SSH est actif : le git push origin main fonctionne pendant une session SSH depuis le laptop.
  • CLAUDE.md est la source de vérité du projet (règles d'ingestion, en-têtes d'auteur obligatoires).
bash
pm2 restart resto-ka                    # après un changement en production

# Déploiement

  • Nœud : M3U96b (Mac Studio, cluster MacLustr) — répertoire ~/apps/resto-ka
  • Port : 8115 (local, exposé uniquement via le tunnel)
  • Processus PM2 : resto-ka (serveur) + resto-ka-sync (synchro) + resto-ka-ngrok (tunnel)
  • Domaine : https://www.resto-ka.com (tunnel ngrok)

# Historique

Jalons tirés du git log :

  • 2026-08-17 — naissance : pipeline connecteurs→SQLite→API (patron Lou·Ka), assets Groupe KA, tableau de bord /stats + rapport PDF, câblage du widget KA Agent.
  • 2026-08-18 — vagues 2-3 d'enrichissement : inspections MAPAQ, horaires structurés, Yelp (API + scraping), avis/notes sans clé, menus livraison, permis d'alcool ; documentation standardisée des sources.
  • 2026-08-19 — Stats v2 (dashboard complet + 5 rapports PDF), campagne mobile (menus tactiles, tabbar), KA Agent v2 plein écran, standard « panneau héro premier dans le DOM ».
  • 2026-08-22 — SEO : SSR léger (JSON-LD Restaurant), sitemaps chunkés, robots.txt ; chaîne de fetch anti-bot résiliente (Oxylabs → Scrapfly → Bright Data) ; section « Récemment consultés ».
  • 2026-08-23 — connecteur site-finder (Serper /maps), photos extraites des sites des restos, Stats v3 (rapports PDF personnalisés, ReportBuilder), favoris unifiés « Mon univers Ka », pages SEO /villes ; 32 → 116 intégrations UEAT découvertes.
  • 2026-08-24 — page documentation /doc (guide + captures + PDF), refonte du README (v2 puis v3), mise à jour du répertoire UEAT.

# Écosystème Groupe KA

Plateforme Vocation
groupe-ka.com portail du groupe et compte unique KA ID
lou-ka.com logements à louer
immo-ka.com propriétés à vendre
vrai-prix.com estimation immobilière
auto-ka.com véhicules
fabri-ka.com produits québécois
food-ka.com épicerie et alimentation
resto-ka.com restaurants (ce repo)
sorti-ka.com sorties et événements
job-ka.com emplois
crea-ka.com créateurs de contenu
trouve-ka.com petites annonces
api-ka.com API de données

# Contact

Simon-Pierre Boucher — fondateur, Groupe KA 📧 contact@spboucher.ai


© Groupe KA — Simon-Pierre Boucher · contact@spboucher.ai Ce repo vit sur spbgit (git.spboucher.ai).

Files · bf2d9fd63c988fbc82a8a6f21b60579ed832c84e
Menu

Theme