Fabri·Ka
Tous les produits québécois. Un seul endroit.
www.fabri-ka.com
Les pastilles « produits / boutiques live / registre QC / régions » sont dynamiques : elles interrogent https://www.fabri-ka.com/api/stats en direct.
Description
Fabri-Ka est le répertoire des produits québécois : un agrégateur de découverte qui recense 384 535 produits (au 2026-08-28, /api/stats live) provenant de 1 580 boutiques en ligne du Québec, couvrant les 17 régions administratives de la province. Chaque produit renvoie vers la boutique d'origine — aucune vente sur Fabri-Ka : les prix, photos et stocks appartiennent aux marchands sources.
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 (4 082 boutiques vérifiées au registre), 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.jsonproduit par la recherche.
Fonctionnalités
- Recherche de produits — plein-texte FTS5 accent-insensible sur 384 535 produits, filtres catégorie / région / origine / prix, tri, pagination, fiches riches (galerie, boutique, produits liés).
- Répertoire de boutiques — 1 580 boutiques avec produits (sur 4 082 vérifiées), fiches enrichies : logo, région, plateforme, stats de prix, politique de livraison (colonne
shipping_info, extraite des pages politiques), catégories, boutiques similaires. - Statistiques — tableau de bord analytique
/stats(module commun ka-stats) : totaux, médianes, histogrammes, ventilation régionale, croissance — et rapports de marché PDF générés à la volée (/api/report.pdf, moteur kapdf, 5 modes + rapports personnalisés). - Catégories — taxonomie de 20 catégories (épicerie fine 44 k · mode 43 k · bijoux 39 k · …) avec ~350 pages programmatiques SEO (
/categorie/erable,/region/monteregie, combinaisons non vides). - Classification d'origine A–E — chaque boutique justifiée par une évidence conservée (certifications Aliments du Québec / Les Produits du Québec, associations, wording du site).
- SEO / SSR — 385 000+ pages indexables : HTML complet dès la 1ʳᵉ requête, JSON-LD schema.org, sitemaps exhaustifs, 301/404/410 propres (détails plus bas).
- « Inscrire mon atelier » — canal d'auto-inscription des artisans (
/inscrire→POST /api/inscriptions) : dépôt public en quarantaine (rien n'est publié sans validation), anti-abus honeypot + 5 dépôts/24 h/IP, décision adminapprove|rejectavec vérification du site par le pipelineverifyavant ajout au registre. - KA ID (SSO) + favoris « Mon univers Ka » synchronisés au hub groupe-ka.com.
- Widget KA Agent — bulle de chat Groupe KA (
ka-agent.js). - Mobile-first — barre d'onglets, filtres en bottom sheet, galeries swipe, CTA collant, PWA-lite, fr-CA d'abord.
- Supervision — connecteurs surveillés par les gardiens autonomes du Groupe KA (agents ka6, supervision api-ka) ;
/api/statsexpose lesync_loget les boutiques désactivées.
Visite guidée
10 captures du site en production (2026-08-28, desktop) — chaque image pointe la page réelle de www.fabri-ka.com.
1 · Accueil — /
La porte d'entrée : masthead vert profond à liseré terracotta, recherche plein-texte immédiate, compteurs live (produits · boutiques · régions), entrées rapides vers les 20 catégories et les 17 régions administratives. Display serif Fraunces, DA v3 « catalogue éditorial ».
2 · Catalogue de produits — /produits
Le cœur du site : 384 535 produits québécois interrogés en plein-texte FTS5 accent-insensible, filtrés par catégorie / région / origine (A–E) / fourchette de prix, triés et paginés. Cartes sans cadre, photos 10 px radius, prix en serif ; chaque carte renvoie vers la boutique d'origine (aucune vente sur Fabri-Ka).
3 · Répertoire des boutiques — /boutiques
1 580 boutiques avec produits en ligne (sur 4 082 vérifiées au registre) : index à filets, logo, région, plateforme ecommerce, nombre de produits. Chaque fiche boutique s'enrichit de stats de prix, de la politique de livraison extraite et de boutiques similaires.
4 · Statistiques — /stats
Le tableau de bord analytique (module commun ka-stats) : totaux, médianes de prix, histogrammes, ventilation régionale et par catégorie, croissance du catalogue — plus les rapports de marché PDF générés à la volée (/api/report.pdf, moteur kapdf, 5 modes + rapports personnalisés).
5 · À propos — /a-propos
La mission expliquée aux visiteurs : pourquoi un agrégateur de produits québécois, comment fonctionne le pipeline de découverte (registre → connecteurs par plateforme → moteur de recherche), et ce que signifient les classes d'origine A–E justifiées par évidence conservée.
6 · Contact — /contact
Le canal de contact du site : questions générales, signalements, et demandes de retrait — tout ayant droit peut demander le retrait de ses données (voir la section conformité).
7 · Inscrire mon atelier — /inscrire
L'auto-inscription des artisans et fabricants : un formulaire public dépose la candidature en quarantaine (POST /api/inscriptions, statut pending — rien n'est publié sans validation). Anti-abus honeypot + limite 5 dépôts/24 h/IP ; à l'approbation, le site est vérifié par le pipeline verify puis ajouté au registre (source auto_inscription) — connecté si un catalogue public répond, sinon fiche annuaire.
8 · Page catégorie — /categorie/alcool
Exemple des pages programmatiques SEO par catégorie : microbrasseries, distilleries, vignobles et cidreries du Québec réunis sous /categorie/alcool, avec compteurs réels, filtres et maillage interne. La taxonomie compte 20 catégories et ~350 pages programmatiques non vides (catégorie × région).
9 · Page région — /region/abitibi-temiscamingue
Le pendant régional : chacune des 17 régions administratives a sa vitrine — ici l'Abitibi-Témiscamingue — listant ses boutiques et produits locaux. Acheter local, au sens propre : le filtre région s'appuie sur la localisation vérifiée des boutiques au registre.
10 · Documentation — /doc/
La page /doc illustrée (standard Groupe Ka) : guide complet de la plateforme avec captures, architecture et FAQ, déclinée en PDF téléchargeable — liée depuis le pied de page de chaque page du site.
Galerie
Captures du 2026-08-25 — DA v3 « catalogue éditorial » (mobile 390×844 · desktop 1440×900).
Mobile
![]() Accueil — masthead vert profond, KA Tabbar |
![]() Catalogue — cartes sans cadre |
![]() Catégorie — érable |
![]() Index des boutiques à filets |
![]() KPI stats en colonnes de chiffres |
|
Desktop
![]() Accueil — display serif Fraunces, sections à règles d'encre |
![]() Catalogue — photos 10px radius + filets |
![]() Page catégorie (SEO programmatique) |
![]() Boutiques — 1 500+ artisans et fabricants |
![]() Statistiques du registre |
|
Nouveautés front-end (2026-08-25) : DA v3 « catalogue éditorial » — display serif Fraunces (titres + prix), masthead et tab bar vert profond à liseré terracotta, cartes produits sans cadre, boutiques en index à filets, KPI stats en colonnes ; KA Tabbar v1 (nav mobile commune Groupe KA).
🗄️ Les captures d'époque sont conservées dans
docs/archive/.
Chiffres (au 2026-08-28, /api/stats live + registre)
| Mesure | Valeur |
|---|---|
| Produits agrégés (catalogues complets) | 384 535 publiés (prix médian ~25 $) |
| Boutiques avec produits en ligne | 1 580 |
Boutiques québécoises vérifiées au registre (data/stores.json) |
4 082 — dont 2 466 avec ecommerce détecté et 1 701 activées pour la sync |
| Régions administratives couvertes | 17 / 17 (Montréal 56 k produits · Outaouais 32 k · Saguenay–Lac-Saint-Jean 24 k · …) |
| Connecteurs plateforme | 10 — boutiques actives : Shopify 718 · WooCommerce 542 · Wix 302 · Votresite.ca 45 · Square 36 · Squarespace 26 · générique 22 · Immunotec 1 · autres 9 |
| Classes d'origine au registre | A : 3 863 · E : 180 · C : 39 |
| Catégories | 20 (épicerie fine 44 k · mode 43 k · bijoux 39 k · …) |
| Pages indexables (produits + boutiques + programmatiques) | 385 000+ |
| Base | data/fabrika.db 3,2 Go (SQLite + FTS5) |
Détails et méthodologie : deliverables/research_report.md · stratégie de découverte continue : deliverables/discovery_strategy.md · conformité par source : docs/CONFORMITE.md.
Stack technique
| Couche | Technologies |
|---|---|
| Backend | Python 3.14 · FastAPI (API + SSR SEO + service du frontend) |
| Base de données | SQLite + FTS5 — upsert par hash de contenu, retraits avec délai de grâce (2 syncs) |
| Frontend | React 18 + Vite + TypeScript — 9 pages, identité famille KA « éditorial sharp » (Space Grotesk + Inter + JetBrains Mono, palette crème/terracotta/pin/miel), tokens ka-ui |
| Connecteurs | Shopify products.json (transport curl anti-429 TLS) · WooCommerce Store API (+ fallback sitemap Yoast/AIOSEO, permaliens personnalisés) · Wix Stores GraphQL · Squarespace ?format=json · Square Online API storefront publique (/app/store/api/v13/…/products, IDs user/site extraits du HTML de la page d'accueil) · Votresite.ca (plateforme QC : Drupal 8 + boutique OpenCart en sous-répertoire — sitemap OpenCart ou crawl des catégories, puis fiche par fiche) · connecteur générique (sitemap → JSON-LD/microdata/OG : PrestaShop, Lightspeed, Snipcart, Magento, sites custom) · Immunotec (storefront sur mesure Next.js/Exigo derrière Cloudflare, via Scrapfly ASP) · Scrapfly/Firecrawl en secours anti-bot. Ecwid non couvert : storefront 100 % client-side (l'API REST v3 exige un token secret — le token pub… de script.js est générique et refusé (403) ; aucun rendu serveur du catalogue, ni sur les instant sites ni via le plugin WordPress) |
| Découverte | 35+ sources : sitemaps d'annuaires, API cachées de cartes (wpgmza, FacetWP), pagination htmx, sessions Firecrawl pour répertoires JS |
| Comptes | KA ID SSO (JWT HS256, stdlib pure) · favoris HMAC-SHA256 vers le hub central |
| Prod | PM2 + ngrok sur le cluster MacLustr (nœud M4M64a) |
Architecture en 30 secondes
flowchart LR
subgraph Discovery["Pipeline de découverte (scripts/)"]
A["35+ annuaires sources<br/>certifications · associations ·<br/>marques régionales · balayages"] --> B["harvest → aggregate →<br/>verify → classify A–E"]
B --> R[("stores.json<br/>4 082 boutiques QC")]
end
subgraph FabriKa["Plateforme (fabrika/)"]
R --> C["Connecteurs plateforme<br/>Shopify · Woo · Wix · Squarespace · Square ·<br/>Votresite.ca · générique (JSON-LD) · Scrapfly"]
C --> D[("SQLite + FTS5<br/>hash + diff")]
D --> E["API FastAPI<br/>/api/products · /api/facets"]
D --> S["Rendu serveur SEO<br/>HTML complet · JSON-LD ·<br/>sitemaps · 301/404/410"]
E --> F["React 18 + Vite<br/>recherche · filtres · fiches"]
S --> G["🕷 Googlebot & co."]
end
H["KA ID (SSO) + favoris<br/>hub groupe-ka.com"] <--> E
W["⏱ Watcher 6 h (PM2)"] -.-> C
F --> U["🍁 Acheteur local"]
SEO & rendu serveur — 385 000+ pages indexables
Le site est une SPA React, mais aucun moteur de recherche ne voit une page vide : le catch-all FastAPI (fabrika/seo.py) injecte dans le HTML du build Vite, pour chaque route, un <head> complet et le contenu essentiel de la page dans #root — React remplace ce contenu au montage (hydratation).
| Élément | Détail |
|---|---|
| Title & meta description uniques | Générés par page à partir des données réelles (compteurs, prix, boutique) |
| Canonical + hreflang fr-CA | Sur chaque page, querystring normalisée |
| Open Graph + Twitter Card | og:image = photo produit / couverture boutique |
| JSON-LD schema.org | Product + Offer (prix CAD, dispo, vendeur), BreadcrumbList, OnlineStore, CollectionPage + ItemList, WebSite + SearchAction |
| Contenu HTML complet | H1, stats, description, galerie (lazy + dimensions), grille de produits, maillage interne |
URLs & statuts propres : slug lisible + uid (/produits/sirop-d-erable-…-b63130ffc8b18c8cc650), 301 de l'uid nu vers l'URL slugée, 410 Gone pour les produits retirés, 404 pour les uid inconnus — fini le soft-404.
Sitemaps & robots : /robots.txt → /sitemap.xml (index) → sitemap-pages.xml + sitemap-boutiques.xml + sitemap-produits-{n}.xml (40 000 URLs/chunk, lastmod réel, régénérés automatiquement, cache 1 h).
Performance : GZip (‑80 % sur le HTML), Cache-Control: immutable sur les assets hashés, images loading="lazy" avec dimensions explicites, polices en swap.
API
| Endpoint | Méthode | Description |
|---|---|---|
/api/products?q=&category=®ion=&origin=&price_min=&price_max=&sort=&page= |
GET | recherche plein-texte + filtres, triée |
/api/products/{uid} |
GET | fiche produit (galerie, boutique, produits liés) |
/api/stores?region=&q=&with_products= |
GET | répertoire des boutiques (logo, région, plateforme) |
/api/stores/{id} |
GET | fiche boutique enrichie : stats de prix, catégories, boutiques similaires |
/api/facets |
GET | catégories/régions/origines avec compteurs |
/api/stats |
GET | totaux live, ventilation régionale, sync_log, boutiques désactivées |
/api/stats/extended |
GET | stats riches : médianes, histogrammes, croissance, ventilation par catégorie |
/api/report.pdf |
GET | rapport de marché PDF — généré à la volée (5 modes + ReportBuilder personnalisé) |
/api/sync |
POST | déclenche une synchronisation en arrière-plan |
/api/inscriptions · …/{id}/decision |
POST/GET | auto-inscription des artisans (« Inscrire mon atelier ») — dépôt public en quarantaine, liste + décision admin |
/api/auth/ka/login → …/callback · /api/auth/me · /api/auth/logout |
GET/POST | SSO KA ID |
/api/favorites · /api/favorites/toggle |
GET/POST | favoris « Mon univers Ka » (hub central) |
/robots.txt · /sitemap.xml (+ sous-sitemaps) |
GET | infrastructure SEO |
Connecteurs & cadences
10 connecteurs plateforme (fabrika/connectors/) pilotés par le registre data/stores.json :
| Connecteur | Boutiques actives | Technique | Cadence |
|---|---|---|---|
shopify.py |
718 | products.json paginé, transport curl anti-429, retry durci |
resync complète aux 6 h |
woocommerce.py |
542 | Store API /wp-json/wc/store/v1/products + fallback sitemap → fiches |
aux 6 h |
wix.py |
302 | GraphQL storefront public (jeton public) | aux 6 h |
votresite.py |
45 | plateforme QC (Drupal 8 + OpenCart) : sitemap ou crawl catégories → fiche par fiche | aux 6 h |
square.py |
36 | API storefront publique v13, IDs extraits du HTML | aux 6 h |
squarespace.py |
26 | ?format=json par collection |
aux 6 h |
generic.py |
22 | sitemap → JSON-LD/microdata/OG (PrestaShop, Lightspeed, Snipcart, Magento, custom) | aux 6 h |
immunotec.py |
1 | storefront sur mesure (Next.js + backend Exigo) derrière Cloudflare — « mur produits » via Scrapfly ASP | aux 6 h |
scrapfly.py / Firecrawl |
secours | rendu JS / anti-bot pour les sites qui bloquent | à la demande |
- Journal
sync_logpar boutique (found/added/updated/removed + raison d'échec), exposé par/api/stats. - Une boutique qui casse n'affecte jamais les autres ; les faux positifs de découverte sont désactivés (
enabled=0) avec garde anti-réintroduction (reprobe_stores.py).
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 — jamais déduite du seul fait qu'une entreprise « semble » québécoise. Répartition au registre (2026-08-28) : A 3 863 · E 180 · C 39.
Structure du projet
fabri-ka/
├── fabrika/ # plateforme
│ ├── web.py # API FastAPI + service du frontend + routes SEO
│ ├── seo.py # rendu serveur : meta, JSON-LD, sitemaps, 301/404/410
│ ├── db.py # SQLite + FTS5, diff par hash, délai de grâce
│ ├── ingest.py # orchestration des syncs par boutique
│ ├── schema.py # modèles Product/Store, taxonomie 20 catégories, 17 régions
│ ├── report.py # rapport de marché PDF généré à la volée
│ ├── auth.py # SSO « KA ID » (JWT HS256, zéro dépendance)
│ ├── hubfav.py # favoris poussés au hub Groupe KA (HMAC)
│ ├── hubprofile.py # profil membre lu du hub
│ ├── inscriptions.py # auto-inscription des artisans (« Inscrire mon atelier », quarantaine)
│ └── connectors/ # shopify · woocommerce · wix · squarespace · square · votresite · immunotec · generic · scrapfly
├── frontend/ # React 18 + Vite + TS — 9 pages, PWA-lite, fr-CA
├── scripts/ # pipeline de découverte (harvest → aggregate → verify → registry),
│ # enrichissements (contacts, livraison, collections), reprobe, docs connecteurs
├── data/ # stores.json (registre 4 082) · fabrika.db (3,2 Go) · caches (non versionnés)
├── deliverables/ # rapport de recherche, CSV des boutiques, sources
├── docs/ # captures d'écran, CONFORMITE.md, fiches des connecteurs
└── run.py # CLI : sync · serve · watchDémarrage rapide
git clone https://git.spboucher.ai/fabri-ka.git && cd fabri-ka # (prod : ssh M4M64a && cd ~/fabri-ka)
# Backend
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
# Frontend (dev : npm run dev ; prod : build servi par FastAPI)
cd frontend && npm install && npm run build && cd ..
# Ingestion puis service
.venv/bin/python run.py sync # toutes les boutiques connectables
.venv/bin/python run.py serve 8097 # → http://localhost:8097
.venv/bin/python run.py watch 360 # resynchronisation en boucle (minutes)
# Après un changement en prod
pm2 restart fabri-ka-web # (ou fabri-ka-sync selon le changement)Variables d'environnement
Noms seulement — les valeurs vivent dans le .env du nœud (jamais dans le repo) :
| Variable | Rôle |
|---|---|
FABRIKA_BASE_URL |
URL publique du site (canonicals, sitemaps) |
FABRIKA_ADMIN_TOKEN |
jeton des opérations d'administration (/api/sync) |
KA_SSO_SECRET · KA_HUB_URL · SESSION_SECRET |
SSO KA ID (JWT HS256) et hub groupe-ka.com |
FIRECRAWL_API_KEY |
sessions Firecrawl (répertoires JS, découverte) |
SCRAPFLY_API_KEY |
secours anti-bot de certains connecteurs |
Données & conformité
- Provenance : le catalogue provient des endpoints publics des boutiques elles-mêmes (Shopify
products.json, WooCommerce Store API, GraphQL Wix, etc.) — pas d'annuaire tiers, aucune donnée derrière authentification. - Revue de conformité par source : chaque source est évaluée AVANT connexion (robots.txt/CGU lus et datés, décision consignée) — voir
docs/CONFORMITE.md(dernière revue complète : 2026-08-19). - Politesse réseau : throttle global par plateforme (Shopify : 0,7 s/req toutes boutiques confondues), backoff 429, caches disque, User-Agent identifié.
- Traçabilité : chaque produit renvoie vers la boutique d'origine ; chaque boutique conserve sa provenance de découverte (
discovery_sources) et son évidence d'origine (origin_evidence). - Cadence : resynchronisation complète aux 6 heures (
run.py watch 360) ; retraits avec délai de grâce (2 syncs). - Retrait sur demande : tout ayant droit peut demander le retrait de ses données (contact ci-dessous).
Déploiement
En production sur le nœud M4M64a du cluster MacLustr (répertoire ~/fabri-ka), servi sur le port 8097 et exposé via ngrok sur www.fabri-ka.com.
3 processus PM2 (vérifiés live) :
fabri-ka-web .venv/bin/python run.py serve 8097 # API + frontend + SSR SEO
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 # tunnelRedéploiement : build + pm2 restart fabri-ka-web (la prod garde sa base data/ — resynchronisée en continu, jamais écrasée).
Développement remote-first (IMPORTANT)
La source de vérité est le repo git sur le nœud M4M64a (~/fabri-ka) — pas une copie locale sur le laptop. Toute modification se fait sur le nœud via SSH : édition, build, pm2 restart, puis commit/push depuis le nœud (agent forwarding actif).
- Remote
origin= spbgit (git perso git.spboucher.ai), via l'alias SSHgitsrv:gitsrv:srv/git/fabri-ka.git— bare repo hébergé sur M3U96a. - Ne pas éditer de copies laptop ; référence complète :
~/Desktop/cluster-skill/KA-REMOTE-DEV.md.
Historique
Jalons réels du repo (git log, 95 commits) :
| Jalon | Commit |
|---|---|
| Naissance — agrégateur de produits québécois | 4d4f1b5 |
| Expansion majeure : 149 500+ produits, 3 131 boutiques, 17/17 régions | a4bbc59 |
| Stats v2 — dashboard ultra complet + 5 rapports PDF (kapdf v2) | 6112f03 |
| Qualité produits — listing_status, quarantaine, prix « sur devis », galeries enrichies | 1f5ecb8 |
| Connecteur Votresite.ca (plateforme QC) — 45 boutiques, +3 190 produits | 037494b |
Stats v3 — rapports PDF personnalisés (ReportBuilder) · gardiens ka6 sur la supervision des connecteurs |
1fbc242 · db542b0 |
Principes
- Politesse — throttle global par plateforme (Shopify : 0,7 s/req toutes boutiques confondues), délais entre requêtes, User-Agent identifié.
- Fidélité — aucun prix inventé ; entités HTML décodées ; si la source ne publie pas une donnée, elle est
null. - Traçabilité — chaque produit renvoie vers la boutique d'origine ; chaque boutique conserve sa provenance de découverte et son évidence d'origine.
- Robustesse — une boutique qui casse n'affecte jamais les autres ; journal
sync_logavec raison d'échec par boutique. - Trouvabilité — tout ce qui existe dans la base existe pour Google : HTML complet, données structurées, sitemaps exhaustifs, jamais de soft-404.
Écosystème Groupe KA
| Plateforme | Univers |
|---|---|
| groupe-ka.com | portail & KA ID |
| lou-ka.com | logements à louer |
| immo-ka.com | propriétés à vendre |
| vrai-prix.com | estimation immobilière |
| auto-ka.com | véhicules |
| fabri-ka.com | produits québécois |
| food-ka.com | épicerie/alimentation |
| resto-ka.com | restaurants |
| sorti-ka.com | sorties et événements |
| job-ka.com | emplois |
| crea-ka.com | créateurs |
| trouve-ka.com | petites annonces |
| api-ka.com | API de données |









