SPB Git

spb/fabri-ka Public

Agrégateur de produits québécois — www.fabri-ka.com

HTML 57.9% Python 18.6% TypeScript 15.6% CSS 7.8%
9.0 KB

# Fabri·Ka

# Tous les produits québécois. Un seul endroit.

www.fabri-ka.com

Python FastAPI React SQLite Firecrawl

Produits Boutiques connectées Registre Connecteurs Régions Sources

Agrégateur de découverte des produits vendus en ligne par les entreprises du Québec — chaque produit renvoie vers la boutique d'origine. Aucune vente sur Fabri-Ka : les prix, photos et stocks appartiennent aux marchands sources.


# Aperçu

Accueil Catalogue Boutiques
Accueil Catalogue Boutiques
Page boutique (landing) Statistiques
Boutique Stats

Version mobile

Mobile-first : barre d'onglets, filtres en bottom sheet, galeries swipe, pages boutiques avec logo/couverture, page statistiques.

# Pourquoi Fabri-Ka ?

Acheter québécois demande de connaître des centaines de boutiques dispersées — érablières, microbrasseries, savonneries, ébénistes, torréfacteurs, fermes… Fabri-Ka retourne le problème : un pipeline de découverte recense les boutiques en ligne du Québec, des connecteurs par plateforme aspirent leurs catalogues publics complets, et un moteur de recherche unique les rend trouvables — filtrés par catégorie, région et origine de fabrication (classes A–E).

Contrairement à un agrégateur classique (1 connecteur / site), Fabri-Ka utilise 1 connecteur / plateforme ecommerce : le même code Shopify sert des centaines de boutiques, piloté par le registre data/stores.json produit par la recherche.

# L'architecture en 30 secondes

flowchart LR
    subgraph Discovery["Pipeline de découverte (scripts/)"]
        A["30+ annuaires sources<br/>certifications · associations ·<br/>marques régionales · balayages"] --> B["harvest → aggregate →<br/>verify → classify A–E"]
        B --> R[("stores.json<br/>3 131 boutiques QC")]
    end
    subgraph FabriKa["Plateforme (fabrika/)"]
        R --> C["Connecteurs plateforme<br/>Shopify · WooCommerce · Wix ·<br/>Squarespace · Scrapfly/Firecrawl"]
        C --> D[("SQLite + FTS5<br/>hash + diff")]
        D --> E["API FastAPI<br/>/api/products · /api/facets"]
        E --> F["React 18 + Vite<br/>recherche · filtres · fiches"]
    end
    W["⏱ Watcher 6 h (PM2)"] -.-> C
    F --> U["🍁 Acheteur local"]
Couche Rôle Fichiers
Découverte Sitemaps d'annuaires, API cachées de cartes (wpgmza, FacetWP), pagination htmx, résolution de redirections affiliées, sessions Firecrawl pour répertoires JS (CMAQ) scripts/harvest.py, scripts/cmaq_firecrawl.py
Vérification Plateforme ecommerce + test réel de l'endpoint catalogue + signaux de localisation QC (codes postaux, indicatifs, TLD, wording) scripts/verify.py
Classification Origine A–E avec évidence conservée (certifications → a priori ; wording du site → ajustement) scripts/build_registry.py
Connecteurs Shopify products.json (transport curl anti-429 TLS), WooCommerce Store API, Wix Stores GraphQL (jeton public), Squarespace ?format=json, Firecrawl en secours fabrika/connectors/
Diff engine Upsert par hash de contenu, retraits avec délai de grâce (2 syncs) fabrika/db.py
API Recherche FTS5 accent-insensible, facettes, filtres catégorie/région/origine/prix, stats, sync fabrika/web.py
Frontend « Chaleur artisanale, précision éditoriale » — Fraunces + Outfit, crème/terracotta/pin, PWA-lite, fr-CA frontend/

# Chiffres (2026-08-12)

Mesure Valeur
Domaines candidats découverts et dédupliqués 3 481
Boutiques québécoises actives vérifiées 3 131
— avec ecommerce détecté 1 970
— connectables par un connecteur plateforme 1 369
Produits agrégés (catalogues complets) 281 000+
Boutiques avec produits en ligne 1 204
Régions administratives couvertes 17 / 17
Classes d'origine A : 3 062 · C : 19 · E : 50

Détails, méthodologie, taux de découverte marginal et angles morts : deliverables/research_report.md · stratégie de découverte continue : deliverables/discovery_strategy.md.

# Démarrage rapide

bash
git clone https://git.spboucher.ai/fabri-ka.git && cd fabri-ka

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

# Frontend
cd frontend && npm install && npm run build && cd ..

# (optionnel) répertoires JS / sites anti-bot
echo "FIRECRAWL_API_KEY=fc-votre-cle" > .env

# Ingestion puis service
.venv/bin/python run.py sync            # toutes les boutiques connectables
.venv/bin/python run.py serve 8090      # → http://localhost:8090
.venv/bin/python run.py watch 360       # resynchronisation en boucle (minutes)

# API

Endpoint Description
GET /api/products?q=&category=&region=&origin=&price_min=&price_max=&sort=&page= Recherche plein-texte + filtres, triée
GET /api/products/{uid} Fiche produit (galerie, boutique, produits liés)
GET /api/stores?region=&q=&with_products= Répertoire des boutiques (logo, région, plateforme)
GET /api/stores/{id} Fiche boutique enrichie : logo, couverture, stats de prix, catégories, boutiques similaires
GET /api/facets Catégories/régions/origines avec compteurs
GET /api/stats Totaux, ventilation régionale, journal de sync
GET /api/stats/extended Statistiques riches : prix (médian/moyen/histogramme), catégories, régions, plateformes, croissance, top boutiques
GET /api/report.pdf Rapport de marché PDF (couverture de marque, KPIs, graphiques, tableaux) — généré à la volée
POST /api/sync Déclenche une synchronisation en arrière-plan

# Classification d'origine

Classe Signification
A Fabriqué / cultivé / transformé au Québec
B Conçu au Québec, fabriqué ailleurs
C Détaillant québécois (revente)
D Mixte
E Incertain — à vérifier

Chaque classe est justifiée par une évidence conservée (certification Aliments du Québec / Les Produits du Québec, adhésion à une association de producteurs, wording du site) — jamais déduite du seul fait qu'une entreprise « semble » québécoise.

# Production

Déployé sous PM2 (3 processus) derrière ngrok sur le nœud M4M64a :

text
fabri-ka-web    .venv/bin/python run.py serve 8097      # API + frontend
fabri-ka-sync   .venv/bin/python run.py watch 360       # resync aux 6 h
fabri-ka-ngrok  ngrok http --url=www.fabri-ka.com 8097  # tunnel

# Principes

  1. Politesse — throttle global par plateforme (Shopify : 0,7 s/req toutes boutiques confondues), délais entre requêtes, User-Agent identifié.
  2. Fidélité — aucun prix inventé ; entités HTML décodées ; si la source ne publie pas une donnée, elle est null.
  3. Traçabilité — chaque produit renvoie vers la boutique d'origine ; chaque boutique conserve sa provenance de découverte et son évidence d'origine.
  4. Robustesse — une boutique qui casse n'affecte jamais les autres ; journal sync_log avec raison d'échec par boutique.

# Auteur

Simon-Pierre Boucher

Email Git

Conçu, construit et déployé en une journée — du recensement provincial (3 131 boutiques vérifiées, 35+ sources) au moteur de recherche en production.

© 2026 Simon-Pierre Boucher — tous droits réservés.