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%
26.5 KB

# CLAUDE.md — Resto·Ka

Agrégateur exhaustif de tous les restaurants du Québec, avec leurs menus complets et leurs prix. Chaque resto, chaque plat, chaque prix — dans les 17 régions, au même endroit, comparable et cherchable.

Ce fichier est la source de vérité pour tout agent Claude (ou humain) qui travaille sur ce dépôt. Lis-le en entier avant d'écrire une seule ligne de code.


# 0. À LIRE EN PREMIER — Règles non négociables

  1. En-tête d'auteur obligatoire. Chaque fichier du dépôt (code, config, doc, script) doit commencer par un en-tête mentionnant l'auteur : Simon-Pierre Boucher <contact@spboucher.ai>. Voir la section 17 pour le format exact selon le type de fichier. Aucun fichier ne doit être commité sans cet en-tête.

  2. Inspire-toi du dépôt Lou·Ka. Avant de concevoir ou d'écrire le moindre connecteur, va lire le dépôt de Lou·Ka (le site jumeau, agrégateur de logements locatifs). Ses connecteurs sont le patron de référence : structure des modules, extraction (Firecrawl / Scrapfly), normalisation, déduplication, gestion des mises à jour, planification des tâches. Ne réinvente rien : reprends les mêmes conventions, la même architecture de connecteur, les mêmes utilitaires partagés. Resto·Ka doit être cohérent avec l'écosystème ·Ka (Lou·Ka, Immo·Ka, Auto·Ka, Food·Ka, Fabri·Ka, Sorti·Ka). Voir section 3.

  3. Travail de moine. L'agrégation de menus est un travail minutieux, source par source, plat par plat, sans rien précipiter. Un menu mal parsé (mauvais prix, plat manquant, option ignorée) détruit la confiance dans toute la base. Mieux vaut un connecteur robuste de plus que dix fragiles.

  4. Vérifie l'existant avant d'ajouter. Avant d'intégrer un resto ou une source, confirme qu'il/elle n'est pas déjà couvert(e) (voir le registre des sources et l'index des restaurants, sections 9 et 12). Ne duplique jamais un connecteur ni une fiche resto. Un restaurant = une fiche canonique, quelles que soient les sources qui l'alimentent.

  5. Chaque source a son connecteur sur mesure, mais les sources qui partagent une même plateforme (livraison, commande en ligne, POS, réservation) doivent être couvertes par un connecteur générique templatisé réutilisable. Voir section 8.

  6. La provenance du prix est sacrée. Un prix de livraison (Uber Eats, DoorDash, Skip) est majoré de 25-30 % par rapport à la salle à manger. Ne jamais présenter un prix sans son contexte (price_context). Voir sections 5 et 11.


# 1. Mission

Rendre visible, en un seul endroit, tous les restaurants du Québec avec leurs menus et leurs prix réels, dans les 17 régions — pour que quiconque puisse répondre à « qu'est-ce que je mange, où, et combien ça coûte ? » sans ouvrir quinze applis.

# Ce qui nous distingue

Les plateformes existantes sont soit des apps de livraison (Uber Eats, Skip, DoorDash — menus complets mais prix majorés, périmètre limité aux restos inscrits et payants), soit des annuaires (Google, Yelp, TripAdvisor — avis et coordonnées, mais pas de menus structurés ni de prix comparables), soit des médias food (Tastet, RestoMontréal — éditorial, pas exhaustif).

Personne n'offre le menu complet + les prix de tous les restos, comparables entre eux, partout au Québec. C'est le créneau de Resto·Ka.


# 2. Périmètre — TOUS les établissements où l'on mange

Périmètre maximaliste. Si on peut y commander à manger, ça doit finir dans Resto·Ka :

  • Restaurants (tous services : gastronomique, décontracté, familial).
  • Fast-food & chaînes (menus standardisés, multi-succursales).
  • Cafés & salons de thé (avec offre alimentaire).
  • Bars & pubs avec cuisine.
  • Comptoirs pour emporter, cantines, casse-croûtes, food trucks.
  • Pizzérias, sushis, poulet, burgers, shawarma, etc.
  • Boulangeries-pâtisseries et traiteurs avec menu et prix.
  • Microbrasseries et établissements avec menu de bouffe.
  • Restaurants d'hôtel, cuisines fantômes (ghost kitchens).

Règle d'or : en cas de doute sur l'inclusion, on inclut et on catégorise par type d'établissement. Le périmètre est large par conception.


# 3. Dépôts de référence — étudier Lou·Ka AVANT de coder

Resto·Ka fait partie de la famille ·Ka. Le dépôt de Lou·Ka est la référence canonique pour l'architecture des connecteurs. Avant tout développement, l'agent Claude doit :

  1. Ouvrir le dépôt de Lou·Ka et localiser le dossier des connecteurs (typiquement connectors/, scrapers/ ou sources/).
  2. Lire 2 ou 3 connecteurs complets de bout en bout pour comprendre :
    • la structure d'un module connecteur (interface commune, méthodes attendues) ;
    • l'extraction (Firecrawl / Scrapfly, endpoints JSON, sitemaps) ;
    • la normalisation vers le schéma commun ;
    • la déduplication (annonces publiées sur plusieurs plateformes) ;
    • la gestion des mises à jour (nouveautés, changements, retraits) ;
    • la planification (cadence, files, retries, backoff), les erreurs et le logging.
  3. Réutiliser les utilitaires partagés de Lou·Ka (client Firecrawl/Scrapfly, helpers de normalisation, déduplication, géocodage) plutôt que d'en réécrire.
  4. Calquer les conventions de nommage, la structure des dossiers et le style de code de Lou·Ka. Un dev qui connaît Lou·Ka doit se retrouver immédiatement.

Adaptation propre à Resto·Ka : là où Lou·Ka normalise une annonce, Resto·Ka normalise un restaurant + un menu imbriqué (catégories → plats → prix → options). Le schéma est plus profond ; le reste du patron s'applique tel quel.

Si tu ne trouves pas le dépôt Lou·Ka ou l'accès aux connecteurs, arrête-toi et demande plutôt que d'inventer une architecture divergente.

Écosystème complet, pour contexte :

Site Domaine Agrège
Lou·Ka lou-ka.com Logements à louer
Immo·Ka immo-ka.com Propriétés à vendre
Auto·Ka auto-ka.com Véhicules usagés
Food·Ka food-ka.com Prix d'épicerie & circulaires
Fabri·Ka fabri-ka.com Produits québécois
Sorti·Ka sorti-ka.com Sorties & événements
Resto·Ka resto-ka.com Restaurants, menus & prix (ce dépôt)

# 4. Architecture

Pipeline standard de la famille ·Ka, adapté aux restaurants et menus :

text
  ┌─────────────┐   ┌──────────────┐   ┌────────────────┐   ┌──────────────┐   ┌──────────┐
  │  CONNECTEUR │──▶│  EXTRACTION  │──▶│  NORMALISATION │──▶│ DÉDUPLICATION │──▶│  STOCKAGE │
  │ (par source)│   │ FC / Scrapfly│   │ resto + menu   │   │ identité resto│   │   (DB)    │
  │             │   │ + parse PDF  │   │ (schéma commun)│   │ + items       │   │           │
  └─────────────┘   └──────────────┘   └────────────────┘   └──────────────┘   └────┬─────┘
                                                                                     │
                                                                          ┌──────────▼──────────┐
                                                                          │  API / RECHERCHE /   │
                                                                          │  UI (menus & prix)   │
                                                                          └─────────────────────┘

Composants :

  • Connecteurs : un module par source (ou par plateforme), interface commune.
  • Orchestrateur : planifie et exécute (cadence, retries, backoff).
  • Extraction : Firecrawl & Scrapfly + clients d'API + parsing de menus PDF / images (OCR) pour les menus non structurés.
  • Normalisation : mappe le brut vers le schéma Restaurant + Menu (section 5).
  • Déduplication : fusionne les restos et les items en double inter-sources.
  • Stockage : base restos + menus + historique des prix (suivi des hausses).
  • API / UI : recherche géolocalisée, filtres (cuisine, prix, diète), comparaison.

# 5. Modèle de données — schéma Restaurant + Menu

# 5.1 Restaurant

jsonc
{
  "id": "string",                    // * id interne canonique (post-déduplication)
  "source_ids": ["ubereats:abc"],    // * id(s) d'origine par source (préfixés)
  "name": "string",                  // * nom normalisé
  "chain": "string|null",            // marque/chaîne si applicable
  "cuisines": ["italien", "pizza"],  // * taxonomie cuisine (section 6)
  "establishment_type": "restaurant",// restaurant|fast-food|cafe|bar|food-truck|traiteur...
  "price_range": "$$",               // $ à $$$$ (estimé à partir des prix)
  "address": "string",               // *
  "city": "string",                  // *
  "region": "string",                // * une des 17 régions (section 7)
  "postal_code": "string",
  "lat": 0.0,                         // * géolocalisation
  "lng": 0.0,                         // *
  "phone": "string",
  "website": "string",
  "hours": { /* horaires par jour */ },
  "services": ["salle", "emporter", "livraison"], // dine-in|takeout|delivery
  "dietary_options": ["vegan", "sans-gluten", "halal"],
  "languages": ["fr", "en"],
  "menu": { /* voir 5.2 */ },
  "status": "open",                  // open|temporarily_closed|closed
  "first_seen": "ISO-8601",          // *
  "last_seen":  "ISO-8601",          // *
  "updated_at": "ISO-8601"           // *
}

# 5.2 Menu (imbriqué)

jsonc
"menu": {
  "currency": "CAD",
  "price_context": "delivery",       // * dine-in | takeout | delivery (voir §6)
  "price_source": "ubereats",        // * source du prix (traçabilité)
  "captured_at": "ISO-8601",         // * quand ce menu/prix a été capté
  "sections": [
    {
      "name": "Pizzas",
      "items": [
        {
          "id": "string",
          "name": "Margherita",       // *
          "description": "string",
          "price": 16.50,             // * prix de l'item (dans price_context)
          "currency": "CAD",
          "tags": ["vegetarien"],
          "options": [                // modificateurs / variantes
            {
              "group": "Format",
              "required": true,
              "choices": [
                { "name": "10 pouces", "price_delta": 0.00 },
                { "name": "14 pouces", "price_delta": 6.00 }
              ]
            }
          ]
        }
      ]
    }
  ]
}

Règles :

  • price_context et price_source sont obligatoires : un prix sans contexte est inutilisable (livraison ≠ salle).
  • lat/lng obligatoires → géocoder l'adresse si absente.
  • Capturer les options/modificateurs (formats, suppléments, choix) : ils changent le prix réel.
  • Conserver la devise partout (CAD). Au QC, TPS/TVQ s'ajoutent ; ne pas les inclure dans price sauf si la source le fait, et alors le documenter.

# 6. Taxonomies

# 6.1 Cuisines (multi-valué)

quebecois · francais · italien · pizza · burgers · poulet · bbq-grillades · fruits-de-mer · sushi-japonais · chinois · thai · vietnamien · coreen · indien · libanais-moyen-orient · mexicain · grec · mediterraneen · dejeuner-brunch · cafe-dessert · vegetarien-vegan · fast-food · autre

# 6.2 Contexte de prix (price_context) — CRITIQUE

  • dine-in — prix en salle (référence idéale).
  • takeout — prix pour emporter (souvent = salle).
  • delivery — prix sur plateforme de livraison, majoré de 25-30 %.

Toujours privilégier dine-in/takeout (menu du resto lui-même ou sa plateforme de commande en ligne) plutôt que delivery quand les deux existent. Si on n'a que delivery, on l'affiche clairement étiqueté.

# 6.3 Diètes / tags

vegan · vegetarien · sans-gluten · halal · casher · sans-noix · epice


# 7. Régions du Québec (obligatoire pour chaque restaurant)

Bas-Saint-Laurent · Saguenay–Lac-Saint-Jean · Capitale-Nationale · Mauricie · Estrie · Montréal · Outaouais · Abitibi-Témiscamingue · Côte-Nord · Nord-du-Québec · Gaspésie–Îles-de-la-Madeleine · Chaudière-Appalaches · Laval · Lanaudière · Laurentides · Montérégie · Centre-du-Québec.

Rattacher chaque resto à sa région via la ville/adresse (table de correspondance ville → région, comme dans Lou·Ka).


# 8. Philosophie des connecteurs

  • Un connecteur par source, taillé sur mesure.
  • Connecteurs templatisés par plateforme : c'est le levier d'échelle nº 1. Une plateforme de commande en ligne ou de livraison couvre des milliers de restos avec la même structure → un seul connecteur paramétré les couvre tous (exactement comme les connecteurs par plateforme d'Auto·Ka et Fabri·Ka).
  • Deux types de sources à combiner :
    1. Découverte (liste des restos + métadonnées) : annuaires, cartes, tourisme.
    2. Menus + prix (le cœur) : commande en ligne, livraison, sites de restos, PDF.
  • Interface commune (à calquer sur Lou·Ka) : fetch() → normalize() → emit(). Idempotent et incrémental quand c'est possible.
  • Robustesse : timeouts, retries + backoff, tolérance aux changements mineurs, alerte si le nombre d'items d'un menu chute anormalement (connecteur cassé).

# 9. Catalogue des sources à connecter (priorisé)

⚠️ Vérifie le registre des sources et l'index des restos avant d'ajouter.

# Palier 1 — Plateformes de commande en ligne des restos (MEILLEUR prix + volume)

Ces plateformes propulsent les sites/apps des restos eux-mêmes → menus complets à des prix réels (dine-in/takeout, non majorés). À templatiser par plateforme :

  • UEAT (foodtech de Québec, marque blanche, très répandue au QC).
  • Square Online Ordering, Toast, Clover, GloriaFood (Oracle), Flipdish, Foodiv, ChowNow, Bite (DoorDash).

# Palier 2 — Plateformes de livraison (menus complets, prix MAJORÉS)

Menus riches et structurés, mais prix delivery (+25-30 %), anti-bot fort et CGU restrictives (voir section 15 — risque légal réel) :

  • Uber Eats, SkipTheDishes, DoorDash.
  • Plateformes québécoises : RestoLoco et autres services locaux régionaux.

Politique : utiliser la livraison surtout pour la découverte et pour les restos qu'on ne trouve nulle part ailleurs. Toujours étiqueter price_context: delivery. Préférer une source dine-in dès qu'elle existe.

# Palier 3 — Sites web des restaurants (menus « maison »)

  • Menus en HTML (parse direct) ou en PDF / image (→ parsing PDF + OCR, voir section 10). Détecter la plateforme de commande embarquée (souvent Palier 1).

# Palier 4 — Découverte & métadonnées (liste des restos)

  • Google Places / Maps, Yelp, TripAdvisor (coordonnées, horaires, type de cuisine, fourchette de prix — rarement les menus ; respecter les CGU/API).
  • Associations touristiques régionales (ATR), Tourisme Québec.
  • Médias food : Tastet, RestoMontréal et annuaires régionaux (découverte).

# Palier 5 — Réservation (métadonnées + parfois menus)

  • OpenTable, LibroReserve (Québec), Resy, Zenchef — horaires, services, parfois menus.

# Palier 6 — Chaînes (menus standardisés)

  • Sites des grandes chaînes : menus et prix souvent uniformes par bannière et parfois par région → un connecteur par chaîne couvre toutes les succursales.

# 10. Extraction — Firecrawl, Scrapfly & parsing de menus

Les connecteurs s'appuient souvent sur Firecrawl et Scrapfly (comme tout l'écosystème ·Ka). Règle de choix :

  • API / endpoint JSON de la plateforme → toujours privilégié (données structurées, stables). Beaucoup de plateformes de commande chargent leur menu via un appel JSON interne : le trouver et le consommer directement.
  • Firecrawl → crawl et extraction en volume de sites relativement ouverts (sites de restos, annuaires), extraction structurée (markdown/JSON).
  • Scrapfly → sites protégés, JavaScript lourd, anti-bot, rendu navigateur, rotation d'IP. Requis pour les plateformes de livraison (Uber Eats, Skip, DoorDash) qui bloquent agressivement.
  • Parsing de menus PDF / images : de nombreux restos publient un menu en PDF ou en photo. Prévoir extraction de texte PDF + OCR + un post-traitement (LLM) qui transforme le texte brut en structure sections → items → price → options. Valider systématiquement (un prix mal OCR-isé est pire que pas de prix).

Chaque connecteur doit documenter en tête de fichier son mode d'extraction et pourquoi. Réutiliser les clients partagés de Lou·Ka.


# 11. Normalisation

  • Nettoyer noms de restos, sections et plats (HTML résiduel, majuscules, doublons).
  • Mapper vers le schéma Restaurant + Menu (section 5) intégralement.
  • Cuisines et type d'établissement classés dès la normalisation (section 6).
  • Géocoder (lat/lng obligatoires) et rattacher la région (section 7).
  • Prix : renseigner obligatoirement price_context et price_source ; capturer les options/modificateurs. Ne jamais mélanger des prix de contextes différents dans un même menu.
  • Devise CAD ; documenter le traitement des taxes (TPS/TVQ hors prix au QC).
  • Conserver les source_ids préfixés (ex. ueat:1234, ubereats:abcd).

# 12. Déduplication — restaurants ET items

Un même resto apparaît sur Uber Eats + DoorDash + Skip + son propre site + Google.

# 12.1 Identité du restaurant

  1. Clé : nom normalisé + adresse (géoloc arrondie) + téléphone → empreinte.
  2. Approché : noms proches + même adresse → fusion candidate (journaliser).
  3. Fusion : un enregistrement canonique, agréger les source_ids, choisir la meilleure source par champ.
  4. Multi-succursales / chaînes : chaque adresse est une fiche resto distincte, reliée par chain. Ne pas fusionner deux succursales.

# 12.2 Menus & prix

  • Ne pas écraser un menu dine-in par un menu delivery : conserver les deux contextes et présenter le meilleur (dine-in prioritaire), en gardant delivery étiqueté.
  • Dédupliquer les items au sein d'un même contexte (même plat listé deux fois).
  • Historiser les prix : à chaque capture, si le prix d'un item change, garder la série temporelle (utile pour détecter les hausses et pour la crédibilité).

S'inspirer de la déduplication de Lou·Ka (multi-plateformes) et d'Auto·Ka (identité forte par clé).


# 13. Fraîcheur des menus & états

  • Menus changeants : prix et plats évoluent (saisonnier, table d'hôte, spéciaux). Rafraîchir régulièrement et horodater chaque capture (captured_at).
  • Fermetures : resto fermé temporairement / définitivement → status mis à jour plutôt que suppression brutale (politique de grâce via last_seen, comme Lou·Ka).
  • Items retirés : disparition d'un plat → le marquer inactif, conserver l'historique.
  • Spéciaux / table d'hôte : capturer si structurés, avec leur période de validité.

# 14. Cadence de rafraîchissement

  • Grandes plateformes (commande en ligne, livraison, chaînes) : hebdomadaire au minimum ; quotidien pour les prix sur les gros volumes urbains.
  • Sites de restos indépendants : hebdomadaire à mensuel (menus stables).
  • Découverte (annuaires) : mensuel pour repérer nouveaux restos / fermetures.
  • Toujours mettre à jour last_seen et captured_at à chaque passage réussi.

# 15. Conformité & aspects légaux — À PRENDRE AU SÉRIEUX

C'est le point le plus sensible de ce projet. Les plateformes de livraison protègent activement leurs données (menus/prix) et l'interdisent dans leurs CGU. Ne pas traiter ça à la légère.

  • Respecter les CGU et robots.txt de chaque source. Les plateformes de livraison sont explicitement restrictives : minimiser, privilégier d'autres sources pour les mêmes restos, et demander en cas de doute avant d'industrialiser.
  • Privilégier les sources de première partie : le site du resto et sa plateforme de commande (UEAT, etc.) sont la voie la plus légitime pour le menu et le prix réel.
  • Rate-limiting raisonnable, identification honnête, pas de surcharge.
  • Utiliser les API officielles quand elles existent (Google Places, Yelp) et en respecter les quotas et conditions d'affichage/attribution.
  • Ne republier que ce qui est nécessaire à la découverte (nom, plats, prix, infos pratiques, lien vers la source). Attribuer les sources requises.
  • Consigner par source la base légale/mode d'accès retenu (API vs scraping) en tête de connecteur.

# 16. Conventions de code

  • Suivre les mêmes conventions que Lou·Ka (langage, structure de dossiers, nommage, linting, formatage). Cohérence > préférences personnelles.
  • Un connecteur = un module isolé, testable indépendamment.
  • Secrets (clés Firecrawl/Scrapfly, API Google/Yelp) via variables d'environnement / gestionnaire de secrets. Jamais en clair.
  • Logging structuré (source, nb de restos, nb d'items, erreurs, durée).
  • Commits atomiques, messages clairs.

# 17. En-tête d'auteur — OBLIGATOIRE dans chaque fichier

Tout fichier du dépôt doit débuter par un en-tête d'auteur. L'auteur est toujours Simon-Pierre Boucher <contact@spboucher.ai>.

Python / Shell / YAML / TOML / Dockerfile :

python
# ==============================================================================
# Author: Simon-Pierre Boucher <contact@spboucher.ai>
# File:   <nom_du_fichier>
# Desc:   <brève description>
# ==============================================================================

JavaScript / TypeScript / Go / Rust / Java / C :

javascript
// ==============================================================================
// Author: Simon-Pierre Boucher <contact@spboucher.ai>
// File:   <nom_du_fichier>
// Desc:   <brève description>
// ==============================================================================

Markdown / HTML / XML :

html
<!--
  Author: Simon-Pierre Boucher <contact@spboucher.ai>
  File:   <nom_du_fichier>
  Desc:   <brève description>
-->

CSS / SCSS :

css
/*
  Author: Simon-Pierre Boucher <contact@spboucher.ai>
  File:   <nom_du_fichier>
*/

Règles :

  • Aucun fichier commité sans cet en-tête.
  • Pour un connecteur, indiquer dans Desc: la source/plateforme couverte, le mode d'extraction (API / Firecrawl / Scrapfly / PDF-OCR) et le contexte de prix produit (dine-in / takeout / delivery).
  • Vérifier la présence de l'en-tête en revue de code (idéalement hook de pré-commit).

# 18. Tests & qualité

  • Chaque connecteur : tests unitaires de normalisation sur des fixtures réelles (réponses JSON, HTML, PDF de menus figés).
  • Tests de parsing de menus : vérifier prix, options et sections sur des échantillons connus (les prix sont l'actif le plus critique).
  • Tests de déduplication resto + items multi-sources.
  • Validation de schéma : tout resto/menu émis doit passer la validation avant stockage ; rejeter un menu sans price_context/price_source.
  • Monitoring : alerte si le nb d'items d'un resto ou le volume d'une source chute anormalement (connecteur probablement cassé).

# 19. Checklist — ajouter un nouveau connecteur / restaurant

  1. Lire les connecteurs de référence dans le dépôt Lou·Ka (section 3).
  2. Vérifier que la source/le resto n'est pas déjà couvert (registres).
  3. Identifier la plateforme : peut-on templatiser/réutiliser un connecteur ?
  4. Choisir le mode d'extraction : API > site du resto > Firecrawl > Scrapfly ; PDF/OCR si menu non structuré (section 10).
  5. Déterminer le price_context produit et le documenter.
  6. Implémenter fetch() → normalize() → emit() (interface commune).
  7. Mapper tout le schéma resto + menu, géocoder, région, cuisines, options.
  8. Brancher la déduplication resto + items (section 12).
  9. Gérer fraîcheur, fermetures, items retirés, historique des prix (§13).
  10. Vérifier la conformité CGU/robots et consigner la base d'accès (§15).
  11. Ajouter l'en-tête d'auteur (section 17).
  12. Écrire les tests + fixtures, dont le parsing de prix (section 18).
  13. Enregistrer la source dans le registre avec sa cadence.
  14. Valider volume et qualité sur un premier run, journaliser.

# 20. Roadmap / MVP

MVP : templatiser un connecteur pour la plateforme de commande en ligne la plus répandue au QC (UEAT) → menus complets à prix réels (dine-in/takeout) pour des milliers de restos d'un coup. Ajouter la découverte via Google Places/Yelp pour la liste et les métadonnées, et le parsing des menus PDF des sites de restos. UI de recherche géolocalisée avec filtres (cuisine, prix, diète, service) et affichage clair du contexte de prix.

Ensuite : plateformes de livraison (avec étiquetage strict), chaînes, réservation, régions moins couvertes. Puis historique des prix, comparaison entre restos, et cross-linking avec les autres sites ·Ka.

Nord stratégique : être le seul à offrir menus et prix comparables de tous les restos du Québec — là où la livraison est chère et partielle, les annuaires sans menus, et les médias food non exhaustifs.


Fin de CLAUDE.md — Resto·Ka. Auteur : Simon-Pierre Boucher <contact@spboucher.ai>.