SPB Git forge

spb/resto-ka

Public

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

52commits 1branches 0releases
11.6 MBsize
maindefault branch
19 days agolast push
Python 69.3% TypeScript 16.7% CSS 7.9% JavaScript 4.7% HTML 1.4%

docs: README v3 — chiffres live vérifiés, pastilles dynamiques, sections complètes

Simon-Pierre Boucher committed 1 mo ago (Aug 24, 2026) parent f1cd42b

1 changed file +149 −66

modified README.md +149 −66
@@ -6,25 +6,48 @@
6 6 <h1 align="center">Resto·Ka</h1>
7 7 <p align="center"><b>Chaque resto, chaque plat, chaque prix</b></p>
8 8
9 −<p align="center">
10 − <a href="https://www.resto-ka.com"><img src="https://img.shields.io/website?url=https%3A%2F%2Fwww.resto-ka.com&style=flat-square&label=www.resto-ka.com&up_color=f08c00&up_message=en%20ligne" alt="Site"></a>
11 − <a href="https://www.resto-ka.com/doc/"><img src="https://img.shields.io/badge/📖_documentation-%2Fdoc-f08c00?style=flat-square" alt="Documentation"></a>
12 − <a href="https://www.resto-ka.com/doc/resto-ka-documentation.pdf"><img src="https://img.shields.io/badge/guide-PDF-f08c00?style=flat-square" alt="PDF"></a>
13 − <img src="https://img.shields.io/badge/n%C5%93ud-M3U96b-1f6feb?style=flat-square" alt="Nœud">
14 − <img src="https://img.shields.io/badge/port-8115-141814?style=flat-square" alt="Port">
15 − <img src="https://img.shields.io/badge/process-PM2-2b037a?style=flat-square" alt="PM2">
16 −</p>
17 −<p align="center">
18 − <img src="https://img.shields.io/badge/Python-3.14-3776AB?style=flat-square&logo=python&logoColor=white" alt="Python">
19 − <img src="https://img.shields.io/badge/FastAPI-API-009688?style=flat-square&logo=fastapi&logoColor=white" alt="FastAPI">
20 − <img src="https://img.shields.io/badge/React_18-Vite_+_TS-087EA4?style=flat-square&logo=react&logoColor=white" alt="React">
21 − <img src="https://img.shields.io/badge/SQLite-menus_+_prix-003B57?style=flat-square&logo=sqlite&logoColor=white" alt="SQLite">
22 − <img src="https://img.shields.io/badge/Groupe-KA-f08c00?style=flat-square" alt="Groupe KA">
23 −</p>
9 +<div align="center">
10 +
11 +<a href="https://www.resto-ka.com"><img src="https://img.shields.io/website?url=https%3A%2F%2Fwww.resto-ka.com&style=flat-square&label=www.resto-ka.com&up_color=f08c00&up_message=en%20ligne" alt="Site"></a>
12 +<a href="https://www.resto-ka.com/healthz"><img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fwww.resto-ka.com%2Fhealthz&query=%24.status&label=sant%C3%A9%20API&color=f08c00&style=flat-square" alt="Santé API (live)"></a>
13 +<a href="https://www.resto-ka.com/doc/"><img src="https://img.shields.io/badge/📖_documentation-%2Fdoc-f08c00?style=flat-square" alt="Documentation"></a>
14 +<a href="https://www.resto-ka.com/doc/resto-ka-documentation.pdf"><img src="https://img.shields.io/badge/guide-PDF-f08c00?style=flat-square" alt="PDF"></a>
15 +<img src="https://img.shields.io/badge/n%C5%93ud-M3U96b-1f6feb?style=flat-square" alt="Nœud">
16 +<img src="https://img.shields.io/badge/port-8115-141814?style=flat-square" alt="Port">
17 +<img src="https://img.shields.io/badge/process-PM2-2b037a?style=flat-square" alt="PM2">
18 +
19 +</div>
20 +
21 +<div align="center">
22 +
23 +<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fwww.resto-ka.com%2Fapi%2Fstats&query=%24.restaurants&label=restaurants&color=f08c00&style=flat-square" alt="Restaurants (live)">
24 +<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fwww.resto-ka.com%2Fapi%2Fstats&query=%24.items&label=plats%20avec%20prix&color=f08c00&style=flat-square" alt="Plats avec prix (live)">
25 +<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fwww.resto-ka.com%2Fapi%2Fstats&query=%24.with_menu&label=menus%20captur%C3%A9s&color=f08c00&style=flat-square" alt="Menus capturés (live)">
26 +<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fwww.resto-ka.com%2Fapi%2Fstats&query=%24.chains&label=cha%C3%AEnes&color=f08c00&style=flat-square" alt="Chaînes (live)">
27 +<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fwww.resto-ka.com%2Fapi%2Fstats&query=%24.regions&label=r%C3%A9gions&color=f08c00&style=flat-square" alt="Régions (live)">
28 +<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fwww.resto-ka.com%2Fapi%2Fstats&query=%24.inspections&label=inspections%20MAPAQ&color=f08c00&style=flat-square" alt="Inspections MAPAQ (live)">
29 +<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fwww.resto-ka.com%2Fapi%2Fstats&query=%24.with_alcohol_permit&label=permis%20alcool&color=f08c00&style=flat-square" alt="Permis d'alcool (live)">
30 +<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fwww.resto-ka.com%2Fapi%2Fstats&query=%24.sources_registry&label=sources%20au%20registre&color=f08c00&style=flat-square" alt="Sources au registre (live)">
31 +
32 +</div>
33 +
34 +<div align="center">
35 +
36 +<img src="https://img.shields.io/badge/Python-3.14-3776AB?style=flat-square&logo=python&logoColor=white" alt="Python">
37 +<img src="https://img.shields.io/badge/FastAPI-API-009688?style=flat-square&logo=fastapi&logoColor=white" alt="FastAPI">
38 +<img src="https://img.shields.io/badge/React_18-TypeScript-087EA4?style=flat-square&logo=react&logoColor=white" alt="React">
39 +<img src="https://img.shields.io/badge/Vite-5-646CFF?style=flat-square&logo=vite&logoColor=white" alt="Vite">
40 +<img src="https://img.shields.io/badge/SQLite-menus_+_prix-003B57?style=flat-square&logo=sqlite&logoColor=white" alt="SQLite">
41 +<img src="https://img.shields.io/badge/PM2-3_processus-2B037A?style=flat-square&logo=pm2&logoColor=white" alt="PM2">
42 +<img src="https://img.shields.io/badge/ngrok-tunnel-1F1E37?style=flat-square&logo=ngrok&logoColor=white" alt="ngrok">
43 +<img src="https://img.shields.io/badge/Groupe-KA-f08c00?style=flat-square" alt="Groupe KA">
44 +<img src="https://img.shields.io/badge/remote--first-spbgit-141814?style=flat-square" alt="remote-first spbgit">
45 +
46 +</div>
24 47
25 48 **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 %).
26 49
27 −**En chiffres** (base de production) : **14 091 restaurants** référencés (découverte OpenStreetMap, 17/17 régions), **79 159 plats avec prix**, **738 restos avec menu complet**, **24 chaînes suivies**, 98 % des items avec photo, 99 % 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.
50 +**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.
28 51
29 52 ## Visite guidée
30 53
@@ -46,7 +69,7 @@
46 69 <td align="center"><img src="docs/screenshots/fiche.png" width="420"><br><sub><b>Fiche restaurant — menu structuré et prix contextualisés</b></sub></td>
47 70 </tr>
48 71 <tr>
49 − <td align="center"><img src="docs/screenshots/plats.png" width="420"><br><sub><b>Recherche par plat — 79 159 items, groupés par marque</b></sub></td>
72 + <td align="center"><img src="docs/screenshots/plats.png" width="420"><br><sub><b>Recherche par plat — 149 569 items, groupés par marque</b></sub></td>
50 73 <td align="center"><img src="docs/screenshots/stats.png" width="420"><br><sub><b>Tableau de bord /stats — le marché resto en chiffres</b></sub></td>
51 74 </tr>
52 75 </table>
@@ -54,77 +77,134 @@
54 77 ## Fonctionnalités
55 78
56 79 - **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.
57 −- **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).
80 +- **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).
58 81 - **Options & formats capturés** avec leurs suppléments (« Mini +3,70 $ ») — ils changent le prix réel.
59 −- **Historique des prix par item** (`item_price_log`) à chaque changement.
82 +- **Historique des prix par item** (`item_price_log`, 155 312 entrées au 2026-08-24) à chaque changement.
60 83 - **Alerte de dérive** — chute anormale du volume d'une source ou du nombre d'items d'un menu → retraits suspendus / ancien menu conservé.
61 −- **Déduplication inter-sources** (les succursales ne sont jamais fusionnées) et **géocodage à 99 %** (Nominatim + Adresses Québec, cache persistant).
62 −- **Découverte OpenStreetMap** (API Overpass) : 13 500+ établissements nommés — 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 29 intégrations de chaînes (Sushi Shop, Valentine, Normandin, Thaïzone, Chez Ashton…).
84 +- **Déduplication inter-sources** (les succursales ne sont jamais fusionnées) et **géocodage à 100 %** (Nominatim + Adresses Québec, cache persistant).
85 +- **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…).
86 +- **Découverte des sites web** des restos OSM (connecteur `site-finder`, Serper /maps) et **extraction des photos** depuis les sites des restos (`site-resto`).
87 +- **Enrichissements officiels** : inspections MAPAQ (2 994 importées, 288 appariées à 204 restos) et permis d'alcool RACJ (1 859 restos).
88 +- **Avis & notes** : Yelp par scraping quotidien (177 restos notés) et croisement Uber Eats (36 restos, prix marqués `delivery`).
63 89 - **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).
64 −- **Registre des sources** — `data/sources.json`, à consulter avant tout ajout (statut et raison des sources non connectables).
90 +- **Registre des sources** — `data/sources.json` (10 sources), à consulter avant tout ajout (statut et raison des sources non connectables).
91 +
92 +## Démarrage rapide
93 +
94 +```bash
95 +# Backend
96 +python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
97 +
98 +# Frontend (build servi par FastAPI)
99 +cd frontend && npm install && npm run build && cd ..
100 +# ou en dev : cd frontend && npm run dev
101 +
102 +# Lancer
103 +.venv/bin/python run.py sync # synchronise (+ géocode + dédup)
104 +.venv/bin/python run.py serve 8115 # API + frontend sur :8115
105 +.venv/bin/python run.py watch 168 # boucle hebdomadaire (heures)
65 106
66 −## API (endpoints principaux)
107 +# Tests (80 tests pytest, fixtures réelles hors ligne)
108 +.venv/bin/python -m pytest tests/
109 +```
110 +
111 +## API (endpoints)
67 112
68 113 Servis par `restoka/web.py` (FastAPI) sur le port 8115.
69 114
70 −| Endpoint | Rôle |
71 −|---|---|
72 −| `GET /api/restaurants` | recherche de restos (ville, région, cuisine, texte libre, pagination) |
73 −| `GET /api/restaurants/{uid}` | fiche complète : menu structuré par contexte de prix, photos, coordonnées |
74 −| `GET /api/restaurants/{uid}/prices` | historique des prix des items du resto |
75 −| `GET /api/restaurants/{uid}/inspections` | inspections/permis (enrichissements MAPAQ) |
76 −| `GET /api/dishes` | recherche par plat dans les 79 159 items, groupée par marque |
77 −| `GET /api/facets` · `GET /api/sources` | facettes de filtres, registre des sources |
78 −| `GET /api/stats` · `/api/stats/dashboard` · `/report` · `/catalog` · `POST /api/stats/report/custom` | tableau de bord + rapports PDF (catalogue et personnalisés) |
79 −| `GET /api/favorites` · `POST /api/favorites/toggle` | favoris « Mon univers Ka » (session KA ID) |
80 −| `POST /api/sync` | déclenchement d'une synchronisation |
81 −| `GET /healthz` | santé du service |
82 −| `GET /doc/` | guide d'utilisation en ligne |
115 +| Méthode | Endpoint | Description |
116 +|---|---|---|
117 +| `GET` | `/api/restaurants` | recherche de restos (ville, région, cuisine, texte libre, `uids=`, pagination) |
118 +| `GET` | `/api/restaurants/{uid}` | fiche complète : menu structuré par contexte de prix, photos, coordonnées, horaires |
119 +| `GET` | `/api/restaurants/{uid}/prices` | historique des prix des items du resto (`item_price_log`) |
120 +| `GET` | `/api/restaurants/{uid}/inspections` | inspections/permis (enrichissements MAPAQ + RACJ) |
121 +| `GET` | `/api/dishes` | recherche par plat dans les 149 569 items, groupée par marque |
122 +| `GET` | `/api/facets` | facettes de filtres (régions, villes, cuisines, types) |
123 +| `GET` | `/api/sources` | registre des sources (statuts, cadences) |
124 +| `GET` | `/api/stats` | statistiques publiques JSON (alimente les pastilles ci-dessus) |
125 +| `GET` | `/api/stats/dashboard` | données du tableau de bord `/stats` |
126 +| `GET` | `/api/stats/report` | rapport PDF principal |
127 +| `GET` | `/api/stats/catalog` | catalogue des rapports disponibles |
128 +| `POST` | `/api/stats/report/custom` | rapport PDF personnalisé (ReportBuilder) |
129 +| `GET` | `/api/favorites` | favoris « Mon univers Ka » (session KA ID) |
130 +| `POST` | `/api/favorites/toggle` | ajout/retrait d'un favori |
131 +| `POST` | `/api/sync` | déclenchement d'une synchronisation |
132 +| `GET` | `/healthz` | santé du service (`{"status":"ok"}`) |
133 +| `GET` | `/doc/` | guide d'utilisation en ligne |
134 +| `GET` | `/{full_path}` | SPA + pages SSR légères (accueil, fiches JSON-LD, /villes) |
83 135
84 136 ## Connecteurs
85 137
86 −Auto-enregistrés dans `restoka/connectors/` (requests direct / Firecrawl / Scrapfly + cache détail dans `base.py`, résilience `_resilient.py`) :
138 +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) :
87 139
88 −| Connecteur | Rôle |
89 −|---|---|
90 −| `osm` | découverte OpenStreetMap (Overpass) — 13 500+ établissements nommés, 17/17 régions |
91 −| `ueat` | connecteur templatisé UEAT (API GraphQL) — menus takeout réels de 29 intégrations de chaînes |
92 −| `siteresto` | menus publiés sur le site des restos indépendants |
93 −| `sitefinder` | découverte du site web / de la plateforme de commande d'un resto |
94 −| `ubereats` | complément livraison (prix marqués `delivery`, jamais prioritaires sur un menu salle) |
95 −| `yelp` · `yelp_scrape` | enrichissement annuaire via yelp.ca (notes, nombre d'avis, gamme de prix, catégories, fermetures) |
140 +| Connecteur | Famille | Rôle | Cadence |
141 +|---|---|---|---|
142 +| `osm` | découverte | OpenStreetMap (Overpass, miroirs fiabilisés) — 13 427 établissements nommés, 17/17 régions | mensuelle |
143 +| `ueat` | menus takeout (tier 1) | connecteur templatisé UEAT (API GraphQL) — menus takeout réels de 116 intégrations découvertes | hebdomadaire |
144 +| `siteresto` | menus salle | menus + photos publiés sur le site des restos indépendants | hebdo (batch incrémental), re-crawl mensuel |
145 +| `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 |
146 +| `ubereats` | livraison | complément livraison (prix `delivery`, jamais prioritaires sur un menu salle) | quotidienne par petits lots (60 pages), re-vérif 30 j |
147 +| `yelp` | annuaire | enrichissement via l'API Yelp Fusion (clé requise — SkipSource sans `YELP_API_KEY`) | hebdo, re-vérification 30 j |
148 +| `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 |
149 +
150 +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.
151 +
152 +## Données & conformité
153 +
154 +- **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.
155 +- **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.
156 +- **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).
157 +- **Données publiques officielles** : inspections MAPAQ et permis d'alcool RACJ (jeux de données gouvernementaux).
158 +- **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.
159 +- La base SQLite de prod (`data/restoka.db`) est **gitignorée** ; aucun secret dans le repo (`.env` local, gabarit `.env.example`).
96 160
97 161 ## Architecture
98 162
99 163 Pipeline (patron Lou·Ka) : **connecteurs → normalisation → déduplication → SQLite → API/frontend**.
100 164
101 −- **Backend Python 3.14 / FastAPI / Uvicorn** (`restoka/web.py`) : API + service du build Vite.
102 −- **SQLite** (`restoka/db.py`) : restos, **menus par contexte de prix**, historique de prix.
165 +- **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).
166 +- **SQLite** (`restoka/db.py`) : restos, **menus par contexte de prix**, historique de prix (`item_price_log`), inspections, favoris, caches détail/géocodage.
103 167 - **Connecteurs auto-enregistrés** (`restoka/connectors/`) : requests direct / Firecrawl / Scrapfly + cache détail (`base.py`), UEAT templatisé (`ueat.py`), découverte Overpass/OSM.
104 168 - **Ingestion** (`restoka/ingest.py`) : sync → geocode → dedup, délai de grâce et alertes de dérive ; enrichissements inspections/permis/heures.
169 +- **Structuration LLM** (`restoka/menullm.py`) : menus maison structurés par Claude (API Anthropic).
105 170 - **Frontend React 18 + Vite + TypeScript** (`frontend/`), design « éditorial sharp » Groupe KA.
106 −- **45 tests pytest** avec fixtures réelles hors ligne.
171 +- **80 tests pytest** avec fixtures réelles hors ligne (connecteurs, normalisation, schéma, horaires, permis…).
107 172
108 −Processus PM2 sur le nœud :
173 +Processus PM2 sur le nœud (commandes de start réelles) :
109 174
110 −| Processus | Rôle | Cadence |
111 −|---|---|---|
112 −| `resto-ka` | serveur FastAPI (API + frontend) sur le port **8115** | continu |
113 −| `resto-ka-sync` | boucle de synchronisation (`run.py watch 168`) | cycle hebdomadaire (168 h) |
114 −| `resto-ka-ngrok` | tunnel ngrok vers **www.resto-ka.com** | continu |
175 +| Processus | Rôle | Commande | Cadence |
176 +|---|---|---|---|
177 +| `resto-ka` | serveur FastAPI (API + frontend) sur le port **8115** | `.venv/bin/python run.py serve 8115` | continu |
178 +| `resto-ka-sync` | boucle de synchronisation | `.venv/bin/python run.py watch 168` | cycle hebdomadaire (168 h) |
179 +| `resto-ka-ngrok` | tunnel vers **www.resto-ka.com** | `ngrok http --url=www.resto-ka.com 8115` | continu |
115 180
116 −Points de configuration notables (variables d'environnement, sans secrets dans le repo) : clés Scrapfly/Firecrawl des connecteurs, secret SSO partagé avec le hub KA ID. Le registre des sources vit dans `data/sources.json` ; la base SQLite de prod est gitignorée.
181 +## Variables d'environnement
182 +
183 +Gabarit : `.env.example` (copier vers `.env`, jamais commité). **Noms seulement — aucune valeur dans le repo.**
184 +
185 +| Variable | Rôle |
186 +|---|---|
187 +| `SCRAPFLY_KEY` | rendu JS + bypass anti-bot (plateformes de livraison) |
188 +| `ANTHROPIC_API_KEY` | structuration des menus maison par Claude (`restoka/menullm.py`) |
189 +| `FIRECRAWL_API_KEY` | rendu JS de secours pour les sites de restos SPA (`site-resto`) |
190 +| `YELP_API_KEY` | API Yelp Fusion (sans clé : source sautée proprement) |
191 +| `YELP_BUDGET` | budget de requêtes Yelp par passage (quota quotidien 500) |
192 +| `SERPER_API_KEY` | Google Maps via Serper — découverte des sites web (`site-finder`) |
193 +| `SITE_FINDER_BUDGET` | budget de requêtes Serper par passage (défaut 3 000) |
194 +| `KA_SSO_SECRET` | SSO Groupe KA (« Se connecter avec KA ») |
195 +| `SESSION_SECRET` | sessions signées |
196 +| `RESTOKA_BASE_URL` | URL publique du site (défaut `https://www.resto-ka.com`) |
117 197
118 198 ## Structure du repo
119 199
120 200 ```
121 201 resto-ka/
122 202 ├── run.py # point d'entrée CLI (sync / watch / serve)
123 −├── restoka/ # cœur Python : web, db, ingest, dedup, geocode, regions, schema, normalize, auth, stats… + connectors/
203 +├── restoka/ # cœur Python : web, db, ingest, dedup, geocode, regions, schema, normalize, auth, stats, menullm… + connectors/
124 204 ├── frontend/ # React 18 + Vite + TypeScript — design éditorial sharp Groupe KA + public/doc/ (guide)
125 −├── data/ # sources.json (registre) + base SQLite de prod (gitignorée)
205 +├── data/ # sources.json (registre), ueat-discovered.json (116 intégrations), base SQLite de prod (gitignorée)
126 206 ├── scripts/ # scripts d'appoint (captures, déploiement)
127 −├── tests/ # 45 tests pytest (fixtures réelles hors ligne)
207 +├── tests/ # 80 tests pytest (fixtures réelles hors ligne)
128 208 └── docs/ # captures d'écran + docs connecteurs
129 209 ```
130 210
@@ -143,14 +223,6 @@ resto-ka/
143 223 - `CLAUDE.md` est la source de vérité du projet (règles d'ingestion, en-têtes d'auteur obligatoires).
144 224
145 225 ```bash
146 −python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
147 −cd frontend && npm install && npm run build && cd ..
148 −
149 −.venv/bin/python run.py sync # synchronise (+ géocode + dédup)
150 −.venv/bin/python run.py serve 8115 # API + frontend
151 −.venv/bin/python run.py watch 168 # boucle hebdomadaire (heures)
152 −.venv/bin/python -m pytest tests/ # 45 tests
153 −
154 226 pm2 restart resto-ka # après un changement en production
155 227 ```
156 228
@@ -161,6 +233,17 @@ pm2 restart resto-ka # après un changement en production
161 233 - **Processus PM2** : `resto-ka` (serveur) + `resto-ka-sync` (synchro) + `resto-ka-ngrok` (tunnel)
162 234 - **Domaine** : **https://www.resto-ka.com** (tunnel ngrok)
163 235
236 +## Historique
237 +
238 +Jalons tirés du `git log` :
239 +
240 +- **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.
241 +- **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.
242 +- **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 ».
243 +- **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 ».
244 +- **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.
245 +- **2026-08-24** — page documentation `/doc` (guide + captures + PDF), refonte du README (v2 puis v3), mise à jour du répertoire UEAT.
246 +
164 247 ## Écosystème Groupe KA
165 248
166 249 | Plateforme | Vocation |
167 250