# Resto·Ka **Tous les restaurants du Québec — menus complets et prix réels, dans les 17 régions.** ![Aperçu de Resto-Ka](docs/screenshot.png) ![Restaurants](https://img.shields.io/badge/restaurants-14_091-141814?labelColor=d9f26b&style=for-the-badge) ![Plats avec prix](https://img.shields.io/badge/plats_avec_prix-79_159-141814?labelColor=d9f26b&style=for-the-badge) ![Régions](https://img.shields.io/badge/r%C3%A9gions-17%2F17-141814?labelColor=d9f26b&style=for-the-badge) ![Chaînes](https://img.shields.io/badge/cha%C3%AEnes_suivies-24-141814?labelColor=d9f26b&style=for-the-badge) ![Menus complets](https://img.shields.io/badge/menus_complets-738_restos-141814?labelColor=d9f26b&style=for-the-badge) ## Description **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**. - **14 091 restaurants** référencés (découverte **OpenStreetMap**, 17/17 régions) - **79 159 plats avec prix** — 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, +25-30 %) - **738 restos avec menu complet**, **24 chaînes suivies** - **98 %** des items avec photo, **69 %** avec options, **99 %** géolocalisés Plateforme de la famille **·Ka** (Lou·Ka, Immo·Ka, Auto·Ka, Food·Ka, Fabri·Ka, Sorti·Ka…). Architecture des connecteurs **calquée sur Lou·Ka**, identité visuelle **« éditorial sharp » du Groupe KA** (Space Grotesk / Inter / JetBrains Mono, papier-encre-lime, bordures encre + ombres décalées). **`CLAUDE.md` est la source de vérité du projet.** ## 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 **79 159 items**, **groupée par marque** (pour ne pas répéter 76 fois la même poutine de chaîne). - **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`) à 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 à 99 %** (Nominatim + Adresses Québec, cache persistant). - **Connexion KA ID** (SSO Groupe Ka), favoris, tableau de bord **Stats** + rapport **PDF**, widget **KA Agent** (chat IA). | Accueil — recherche de restos | Recherche par plat | |---|---| | ![Accueil](docs/screenshots/accueil.png) | ![Plats](docs/screenshots/plats.png) | | Fiche resto — menu, photos, options & prix | Couverture en direct | |---|---| | ![Fiche](docs/screenshots/fiche.png) | ![Stats](docs/screenshots/stats.png) | ## Stack technique - **Backend** : **Python 3.14** · **FastAPI** · **Uvicorn** · **SQLite** (menus par contexte + historique de prix) - **Frontend** : **React 18** · **Vite** · **TypeScript** — design éditorial sharp Groupe KA - **Scraping/ingestion** : requests direct / **Firecrawl** / **Scrapfly**, API **Overpass** (OSM), API **GraphQL UEAT** - **Tests** : **45 tests pytest** (fixtures réelles hors ligne) ## Structure (patron Lou·Ka) ``` restoka/ ├── connectors/ # un module par source/plateforme, auto-enregistrés │ ├── base.py # requests direct / Firecrawl / Scrapfly + cache détail │ └── ueat.py # UEAT (templatisé) — API GraphQL, prix TAKEOUT réels ├── schema.py # Restaurant + menu imbriqué (sections→items→options) + finalize() ├── normalize.py # prix, cuisines, type d'établissement, diètes, $-$$$$ ├── regions.py # ville → 17 régions (+ repli postal, + repli lat/lng) ├── db.py # SQLite : restos, menus PAR CONTEXTE, historique de prix ├── ingest.py # pipeline sync → geocode → dedup (délai de grâce, alertes) ├── dedup.py # identité resto inter-sources (succursales jamais fusionnées) ├── geocode.py # Nominatim + Adresses Québec, cache persistant ├── auth.py # connexion KA ID (SSO Groupe Ka) └── web.py # FastAPI + frontend React (frontend/dist) frontend/ # Vite + React 18 + TS — design éditorial sharp Groupe KA ``` ## Sources connectées Registre : **`data/sources.json`** (à consulter **AVANT** d'ajouter quoi que ce soit). | Source | Palier | Contexte de prix | Couverture | |--------|--------|------------------|------------| | **OpenStreetMap** (découverte, API Overpass) | 4 | — (fiches sans menu) | **13 500+ établissements** : tous les restos, fast-foods, cafés, bars, crèmeries et boulangeries nommés du Québec — **17/17 régions**. Données © contributeurs OSM (ODbL). | | **UEAT** (commande en ligne, API GraphQL anonyme) | 1 | **`takeout` (prix réels)** | **29 intégrations** : Sushi Shop (141), Poulet Rouge (82), Valentine (76), Normandin (44), Chocolats Favoris (41), Allô mon Coco (34), Thaïzone (26), Scores (25), Chez Ashton (23), Pacini (20), Boustan (65), Ben & Florentine (54), Pizzéria NO.900 (32), Sushi Taxi (30), Tutti Frutti, Mandy's, Cochon Dingue, Panda Boba-T, Salvatoré, Ryu Sushi, Impérial, La Belle Province, Madisons, Pizza Mia, Station W, Freddy, Le Super Qualité, Château Frontenac | | St-Hubert | 6 | `takeout` (visé) | à faire — anti-bot Akamai, voir `data/sources.json` | ## Démarrage local ```bash python3 -m venv .venv && .venv/bin/pip install -r requirements.txt cd frontend && npm install && npm run build && cd .. .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 .venv/bin/python -m pytest tests/ # 45 tests (fixtures réelles hors ligne) ``` ## Déploiement - **Nœud** : **M3U96b** (cluster MacLustr), répertoire **`~/apps/resto-ka`** - **Port** : **8115** - **Domaine** : **[www.resto-ka.com](https://www.resto-ka.com)** (tunnel **ngrok**) - **PM2** (3 process) : **`resto-ka`** (serveur :8115) + **`resto-ka-sync`** (synchro hebdomadaire) + **`resto-ka-ngrok`** (tunnel → www.resto-ka.com) - Registre cross-session : `~/Desktop/cluster-skill/cluster-deployments.json` ## Développement remote-first **La source de vérité est le repo git sur le nœud M3U96b** (`~/apps/resto-ka`), **PAS** les copies laptop. Toute modification se fait **sur le nœud via SSH** : édition, build, `pm2 restart resto-ka`, puis `git add/commit/push origin main` **sur le nœud** (agent forwarding actif). - Remote **`origin`** = **spbgit** (git perso **git.spboucher.ai** — bare repo `~/srv/git/resto-ka.git` sur M3U96a, alias SSH `gitsrv`). **PAS GitHub.** - Référence complète : `~/Desktop/cluster-skill/KA-REMOTE-DEV.md`. --- Un service **[Groupe Ka](https://www.groupe-ka.com)** — Auteur : Simon-Pierre Boucher \.