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](https://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-28) : **21 217 restaurants actifs** (hors doublons, découverte OpenStreetMap + registre alimentaire de Montréal, 17/17 régions), **163 677 plats avec prix**, **1 874 menus capturés** (1 324 takeout · 496 salle · 57 livraison), **188 chaînes identifiées** dont **116+ intégrations UEAT découvertes**, **3 001 inspections MAPAQ** importées (661 croisées sur 443 restos), **3 001 restos avec permis d'alcool** (RACJ), 220 restos notés Yelp, **17 sources au registre**, 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 > ⚠️ **Application archivée le 2026-09-04** — l'URL live (https://www.resto-ka.com) est hors fonction ; l'app a été retirée du cluster MacLustr (registre mld, admin-ka, gardiens, site groupe-ka). Ce dépôt spbgit reste la source de vérité pour une remise en service. *Captures live du 2026-08-28 sur [www.resto-ka.com](https://www.resto-ka.com) — desktop 1440×900, mobile 390×844.*
Accueil
Accueil — héros typographique « Chaque resto, chaque plat, chaque prix », recherche par resto ou par plat, bande « signes vitaux » live (restos, plats, menus, régions) sur fond encre.
Répertoire des villes
Répertoire des villes (/villes) — les villes du Québec classées par région administrative, avec le compte de restos ; pages SEO indexables.
Statistiques
Statistiques (/stats) — tableau de bord complet : volumes par région, contextes de prix, chaînes, inspections, sources ; rapports PDF (catalogue + ReportBuilder personnalisé).
Sources de données
Sources (/sources) — le registre public des 17 sources de données : rôle, statut, cadence et dernières synchronisations, en toute transparence.
Contact
Contact (/contact) — coordonnées du Groupe KA, formulaire, et liens vers les autres plateformes de l'écosystème.
Restos de Montréal
Page ville — Montréal (/ville/montreal) — près de 12 000 restos montréalais, filtres par cuisine et type, cartes à filets d'encre avec ombre safran au survol.
Fiche restaurant
Fiche restaurant (/resto/<uid>) — panneau héros (nom, cuisine, adresse), coordonnées et horaires structurés, menu par contexte de prix, inspections MAPAQ et permis d'alcool, carte.
Favoris
Favoris (/favoris) — « Mon univers Ka » : les restos sauvegardés avec le compte unique KA ID, partagés entre les 12 plateformes du groupe.
Documentation
Documentation (/doc/) — guide d'utilisation illustré en 4 étapes + version PDF téléchargeable.
Accueil mobile
Accueil mobile (390×844) — recherche plein pouce, signes vitaux compacts et KA Tabbar (barre de navigation mobile commune Groupe KA).
> 🗄️ Les captures du front-end v2 du 2026-08-25 (webp) restent dans [`docs/screenshots/mobile/`](docs/screenshots/mobile/) et [`docs/screenshots/desktop/`](docs/screenshots/desktop/) ; les captures d'époque sont conservées dans [`docs/archive/`](docs/archive/). ### Nouveautés front-end (2026-08-25) - **Front-end v2 « éditorial premium »** — bande signes vitaux pleine largeur (chiffres géants tabulaires sur fond encre), nav soulignée, héros typographique agrandi, cartes/plats/menus/filtres allégés (filets d'encre au lieu de boîtes), ombre safran signature au survol. - **KA Tabbar v1** — barre de navigation mobile commune Groupe KA. - **7 nouvelles sources** — mtl-alim, Tastet, ChowNow, GloriaFood, Square, DoorDash, Skip + hub de découverte multi-plateformes. - **Widget ka-agent v4** — cartes de restos cliquables et choix en boutons. ## 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 163 677 items (au 2026-08-28), 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 000+ entrées) à 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é (visible dans les syncs récents : les runs partiels de Tastet sont signalés et les retraits suspendus). - **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) : 14 008 établissements nommés au dernier passage — restos, fast-foods, cafés, bars, crèmeries, boulangeries — dans les 17 régions, complétée par le **registre alimentaire de la Ville de Montréal** (`mtl-alim`, 7 574 établissements, données ouvertes) et le média resto **Tastet** ; **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 (connecteur `site-finder`, Serper /maps — sites, téléphones, liens de réservation) et **extraction des menus + photos** depuis les sites des restos (`site-resto`). - **Hub multi-plateformes de commande** : connecteurs templatisés ChowNow, GloriaFood et Square Online (menus takeout réels, activés dès qu'une intégration est découverte par `site-finder`). - **Enrichissements officiels** : inspections MAPAQ (3 001 importées, 661 appariées à 443 restos) et permis d'alcool RACJ (3 001 restos). - **Avis & notes** : Yelp par scraping quotidien (220 restos notés) et croisement des plateformes de livraison Uber Eats, DoorDash et Skip (prix marqués `delivery`, jamais prioritaires). - **Connexion KA ID** (SSO Groupe KA), favoris unifiés « Mon univers Ka », recommandations personnalisées (moteur `kaid` v2, filtrage collaboratif ALS), tableau de bord `/stats` + rapports PDF (catalogue + ReportBuilder), widget **KA Agent v4** (chat IA, cartes de restos cliquables). - **Registre des sources** — `data/sources.json` (**17 sources**), exposé publiquement sur [/sources](https://www.resto-ka.com/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 (110 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 163 677 items, groupée par marque | | `GET` | `/api/facets` | facettes de filtres (régions, villes, cuisines, types) | | `GET` | `/api/sources` | registre des sources (statuts, cadences) — alimente la page `/sources` | | `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, /ville/:slug) | ## 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) — 14 008 établissements nommés, 17/17 régions | mensuelle | | `mtl-alim` | découverte | registre des établissements alimentaires de la Ville de Montréal (données ouvertes) — 7 574 établissements | mensuelle | | `tastet` | découverte / éditorial | restos recensés par le média Tastet (sélections montréalaises) | hebdomadaire | | `sitefinder` | découverte | sites web / téléphones / liens de réservation / plateformes de commande des restos (Serper /maps) | hebdo par lots (3 000 req.), échecs re-sondés 180 j | | `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 | | `chownow` | menus takeout | connecteur templatisé ChowNow — dormant (activé dès qu'une intégration est découverte) | hebdomadaire | | `gloriafood` | menus takeout | connecteur templatisé GloriaFood — dormant (activé dès qu'une intégration est découverte) | hebdomadaire | | `squareonline` | menus takeout | connecteur templatisé Square Online — 1 intégration active | hebdomadaire | | `ubereats` | livraison | complément livraison (prix `delivery`, jamais prioritaires sur un menu salle) | quotidienne par petits lots (60 pages), re-vérif 30 j | | `doordash` | livraison | croisement DoorDash (menus `delivery`) | quotidienne par petits lots | | `skip` | livraison | croisement SkipTheDishes (menus `delivery`) | quotidienne par petits lots | | `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` — **17 sources** au 2026-08-28 (**12 actives**, 3 dormantes en attente d'intégrations découvertes : chownow, gloriafood, square, 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. Version publique : [/sources](https://www.resto-ka.com/sources). - **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 ; ChowNow/GloriaFood/Square Online templatisés) 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, DoorDash/Skip par petits lots). - **Données publiques officielles** : inspections MAPAQ, permis d'alcool RACJ et registre alimentaire de la Ville de Montréal (jeux de données gouvernementaux/municipaux ouverts). - **Cadence de resync** : boucle `run.py watch 168` (cycle hebdomadaire) ; les sources quotidiennes (yelp-scrape, ubereats, doordash, skip) 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`), hub multi-plateformes (chownow/gloriafood/squareonline), découverte Overpass/OSM + mtl-alim + Tastet. - **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 premium » Groupe KA (v2 2026-08-25). - **110 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 ``` 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 premium Groupe KA + public/doc/ (guide) ├── data/ # sources.json (registre), ueat-discovered.json (intégrations), base SQLite de prod (gitignorée) ├── scripts/ # scripts d'appoint (captures, déploiement) ├── tests/ # 110 tests pytest (fixtures réelles hors ligne) └── docs/ # screenshots/ (visite guidée + v2 webp), archive/, connecteurs/ (docs par source) ``` ## Documentation - **Guide en ligne** : [www.resto-ka.com/doc/](https://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](https://www.resto-ka.com/doc/resto-ka-documentation.pdf) — la même documentation, téléchargeable. - **Docs des connecteurs** : [`docs/connecteurs/`](docs/connecteurs/) — une fiche par source (accès, extraction, cadence, gotchas), index dans `INDEX.md`. - 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](https://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. - **2026-08-25** — front-end v2 « éditorial premium », KA Tabbar v1, **7 nouvelles sources** (mtl-alim, Tastet, ChowNow, GloriaFood, Square, DoorDash, Skip) + hub de découverte multi-plateformes, widget ka-agent v4 ; le volume passe de ~14,7 k à 21 k+ restos. - **2026-08-26/27** — KA ID v2 : recommandations personnalisées (`kaid.py`, filtrage collaboratif ALS, pilules « Sauvegarder cette recherche »/« Pas pour moi »), alignées sur `ka-ui.git`. - **2026-08-28** — README v4 : visite guidée en 10 captures live (`docs/screenshots/`), chiffres et registre des sources à jour. ## Écosystème Groupe KA | Plateforme | Vocation | |---|---| | [groupe-ka.com](https://www.groupe-ka.com) | portail du groupe et compte unique KA ID | | [lou-ka.com](https://www.lou-ka.com) | logements à louer | | [immo-ka.com](https://www.immo-ka.com) | propriétés à vendre | | [vrai-prix.com](https://www.vrai-prix.com) | estimation immobilière | | [auto-ka.com](https://www.auto-ka.com) | véhicules | | [fabri-ka.com](https://www.fabri-ka.com) | produits québécois | | [food-ka.com](https://www.food-ka.com) | épicerie et alimentation | | [resto-ka.com](https://www.resto-ka.com) | restaurants *(ce repo)* | | [sorti-ka.com](https://www.sorti-ka.com) | sorties et événements | | [job-ka.com](https://www.job-ka.com) | emplois | | [crea-ka.com](https://www.crea-ka.com) | créateurs de contenu | | [trouve-ka.com](https://www.trouve-ka.com) | petites annonces | | [api-ka.com](https://www.api-ka.com) | API de données | ## Contact **Simon-Pierre Boucher** — fondateur, Groupe KA 📧 [contact@spboucher.ai](mailto:contact@spboucher.ai) --- © Groupe KA — Simon-Pierre Boucher · contact@spboucher.ai Ce repo vit sur **spbgit** ([git.spboucher.ai](https://git.spboucher.ai)).