SPB Git forge

spb/fabri-ka

Public

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

217commits 1branches 0releases
66.1 MBsize
maindefault branch
3 h agolast push
Python 38.4% HTML 30.3% TypeScript 17.2% CSS 11% JavaScript 3.2%

[ka6] nouveau connecteur Votresite.ca (plateforme e-commerce québécoise) — 45 boutiques débloquées, +3 190 produits: le pool de 1 045 boutiques du registre sans plateforme cachait 61 sites Votresite.ca (vitrine Drupal 8 gérée, thème owebo-votresite, boutique OpenCart montée en sous-répertoire /boutique|/produits|/shop). VotresiteConnector: montage détecté (registre → page d'accueil → chemins usuels), inventaire par <mount>/sitemap.xml (extension OpenCart pas toujours activée) sinon crawl des catégories <mount>/fr avec ?limit=100&page=N, puis fiche par fiche …/<slug>-p<ID>/ (rendu 100 % serveur, aucune API). Pièges gérés: prix courant = <h2>…$</h2> et barré = span line-through (twitter:data1 affiche le prix RÉGULIER même en solde, gardé en secours), titre = dernier <h1> sans ancre (le 1er h1 est le logo-lien, og:title parfois bourré de mots-clés), dédup par ID produit (même p<ID> sous plusieurs chemins -p361c37c45c44), images OpenCart aux espaces bruts encodées. Registre: 45/61 boutiques confirmées live → platform=votresite + endpoint, les 16 autres sans boutique réelle (archivées/fermées) restent inertes. Sync réel: 45 ok / 0 erreur, 3 190 produits (bijouteriesimard 488, zylvery 312, alpagadore 238, monastère 174, vivelesepices 166…), 4 fiches vérifiées à la main contre la source (titre/prix/solde/modèle/dispo). Docs régénérées (fiche votresite.md), README 8→9 connecteurs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Simon-Pierre Boucher committed 1 mo ago (Aug 23, 2026) parent c715bd2

17 changed files +671 −272

modified README.md +2 −2
@@ -15,7 +15,7 @@
15 15 ![Produits](https://img.shields.io/badge/produits_agr%C3%A9g%C3%A9s-301_534-234438?style=flat-square)
16 16 ![Boutiques connectées](https://img.shields.io/badge/boutiques_avec_produits-1_377-234438?style=flat-square)
17 17 ![Registre](https://img.shields.io/badge/boutiques_QC_v%C3%A9rifi%C3%A9es-3_507-234438?style=flat-square)
18 −![Connecteurs](https://img.shields.io/badge/connecteurs_plateforme-8-234438?style=flat-square)
18 +![Connecteurs](https://img.shields.io/badge/connecteurs_plateforme-9-234438?style=flat-square)
19 19 ![Régions](https://img.shields.io/badge/r%C3%A9gions_couvertes-17%2F17-234438?style=flat-square)
20 20 ![Sources](https://img.shields.io/badge/sources_de_d%C3%A9couverte-35%2B-234438?style=flat-square)
21 21
@@ -77,7 +77,7 @@ Acheter québécois demande de connaître des centaines de boutiques dispersées
77 77 | **Backend** | **Python 3.14** · **FastAPI** (API + SSR SEO + service du frontend) |
78 78 | **Base de données** | **SQLite + FTS5** — upsert par **hash de contenu**, retraits avec délai de grâce (2 syncs) |
79 79 | **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** |
80 −| **Connecteurs** | **Shopify** `products.json` (transport curl anti-429 TLS) · **WooCommerce** Store API · **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) · **connecteur générique** (sitemap → JSON-LD/microdata/OG : PrestaShop, Lightspeed, Snipcart, Magento, sites custom) · **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) |
80 +| **Connecteurs** | **Shopify** `products.json` (transport curl anti-429 TLS) · **WooCommerce** Store API · **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) · **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) |
81 81 | **Découverte** | **35+ sources** : sitemaps d'annuaires, API cachées de cartes (wpgmza, FacetWP), pagination htmx, sessions **Firecrawl** pour répertoires JS |
82 82 | **Comptes** | **KA ID** SSO (JWT HS256, stdlib pure) · favoris HMAC-SHA256 vers le hub central |
83 83 | **Prod** | **PM2** + **ngrok** sur le cluster **MacLustr** |
modified data/stores.json +154 −154
@@ -3418,8 +3418,8 @@
3418 3418 "id": "alpagadore.com",
3419 3419 "name": "AlpagAdore",
3420 3420 "url": "https://alpagadore.com",
3421 − "platform": "",
3422 − "catalog_endpoint": "",
3421 + "platform": "votresite",
3422 + "catalog_endpoint": "/boutique",
3423 3423 "city": "",
3424 3424 "region": "Montérégie",
3425 3425 "postal_prefix": "J0S",
@@ -3444,7 +3444,7 @@
3444 3444 "ecommerce": true,
3445 3445 "verification_date": "2026-08-12",
3446 3446 "status": "verified",
3447 − "enabled": false,
3447 + "enabled": true,
3448 3448 "last_reprobe": "2026-08-19",
3449 3449 "geo": {
3450 3450 "lat": 45.0131,
@@ -5311,8 +5311,8 @@
5311 5311 "id": "artcimentdecoration.ca",
5312 5312 "name": "Art Ciment décoration",
5313 5313 "url": "https://artcimentdecoration.ca",
5314 − "platform": "",
5315 − "catalog_endpoint": "",
5314 + "platform": "votresite",
5315 + "catalog_endpoint": "/boutique",
5316 5316 "city": "",
5317 5317 "region": "",
5318 5318 "postal_prefix": null,
@@ -5334,10 +5334,10 @@
5334 5334 "Art Ciment décoration Julie Bellemare québec"
5335 5335 ],
5336 5336 "language": "fr",
5337 − "ecommerce": false,
5337 + "ecommerce": true,
5338 5338 "verification_date": "2026-08-12",
5339 5339 "status": "verified",
5340 − "enabled": false,
5340 + "enabled": true,
5341 5341 "last_reprobe": "2026-08-19"
5342 5342 },
5343 5343 {
@@ -13016,8 +13016,8 @@
13016 13016 "id": "bijouteriebrouillette.ca",
13017 13017 "name": "Bijouterie Brouillette",
13018 13018 "url": "https://bijouteriebrouillette.ca",
13019 − "platform": "",
13020 − "catalog_endpoint": "",
13019 + "platform": "votresite",
13020 + "catalog_endpoint": "/boutique",
13021 13021 "city": "",
13022 13022 "region": "",
13023 13023 "postal_prefix": null,
@@ -13039,7 +13039,7 @@
13039 13039 "ecommerce": true,
13040 13040 "verification_date": "2026-08-12",
13041 13041 "status": "probable",
13042 − "enabled": false,
13042 + "enabled": true,
13043 13043 "last_reprobe": "2026-08-19"
13044 13044 },
13045 13045 {
@@ -13467,8 +13467,8 @@
13467 13467 "id": "bijouteriesimard.ca",
13468 13468 "name": "Bijouterie Simard",
13469 13469 "url": "https://bijouteriesimard.ca",
13470 − "platform": "",
13471 − "catalog_endpoint": "",
13470 + "platform": "votresite",
13471 + "catalog_endpoint": "/boutique",
13472 13472 "city": "",
13473 13473 "region": "Saguenay–Lac-Saint-Jean",
13474 13474 "postal_prefix": null,
@@ -13490,7 +13490,7 @@
13490 13490 "ecommerce": true,
13491 13491 "verification_date": "2026-08-12",
13492 13492 "status": "probable",
13493 − "enabled": false,
13493 + "enabled": true,
13494 13494 "last_reprobe": "2026-08-19"
13495 13495 },
13496 13496 {
@@ -18064,8 +18064,8 @@
18064 18064 "id": "bourdeauartistepeintre.com",
18065 18065 "name": "Bourdeau artiste peintre",
18066 18066 "url": "https://bourdeauartistepeintre.com",
18067 − "platform": "",
18068 − "catalog_endpoint": "",
18067 + "platform": "votresite",
18068 + "catalog_endpoint": "/boutique",
18069 18069 "city": "",
18070 18070 "region": "Capitale-Nationale",
18071 18071 "postal_prefix": null,
@@ -18089,10 +18089,10 @@
18089 18089 "https://www.tourisme-charlevoix.com/fr/entreprises/bourdeau-artiste-peintre"
18090 18090 ],
18091 18091 "language": "fr",
18092 − "ecommerce": false,
18092 + "ecommerce": true,
18093 18093 "verification_date": "2026-08-12",
18094 18094 "status": "verified",
18095 − "enabled": false,
18095 + "enabled": true,
18096 18096 "last_reprobe": "2026-08-19"
18097 18097 },
18098 18098 {
@@ -20455,8 +20455,8 @@
20455 20455 "id": "britanniamills.com",
20456 20456 "name": "Domaine Britannia Mills",
20457 20457 "url": "https://britanniamills.com",
20458 − "platform": "",
20459 − "catalog_endpoint": "",
20458 + "platform": "votresite",
20459 + "catalog_endpoint": "/shop",
20460 20460 "city": "",
20461 20461 "region": "Montérégie",
20462 20462 "postal_prefix": "J0H",
@@ -20480,10 +20480,10 @@
20480 20480 "https://alimentsduquebec.com/entreprises/domaine-britannia-mills"
20481 20481 ],
20482 20482 "language": "fr",
20483 − "ecommerce": false,
20483 + "ecommerce": true,
20484 20484 "verification_date": "2026-08-12",
20485 20485 "status": "verified",
20486 − "enabled": false,
20486 + "enabled": true,
20487 20487 "last_reprobe": "2026-08-19",
20488 20488 "geo": {
20489 20489 "lat": 45.6125,
@@ -22243,8 +22243,8 @@
22243 22243 "id": "cabanetilouisbrochu.com",
22244 22244 "name": "Cabane chez Ti-Louis Brochu",
22245 22245 "url": "https://cabanetilouisbrochu.com",
22246 − "platform": "",
22247 − "catalog_endpoint": "",
22246 + "platform": "votresite",
22247 + "catalog_endpoint": "/boutique",
22248 22248 "city": "",
22249 22249 "region": "Chaudière-Appalaches",
22250 22250 "postal_prefix": "G0S",
@@ -22271,7 +22271,7 @@
22271 22271 "ecommerce": true,
22272 22272 "verification_date": "2026-08-12",
22273 22273 "status": "probable",
22274 − "enabled": false,
22274 + "enabled": true,
22275 22275 "last_reprobe": "2026-08-19",
22276 22276 "geo": {
22277 22277 "lat": 46.2635,
@@ -26378,8 +26378,8 @@
26378 26378 "id": "centrefrancinethibeault.com",
26379 26379 "name": "Centre Santé-Beauté Francine Thibeault",
26380 26380 "url": "https://centrefrancinethibeault.com",
26381 − "platform": "",
26382 − "catalog_endpoint": "",
26381 + "platform": "votresite",
26382 + "catalog_endpoint": "/boutique",
26383 26383 "city": "",
26384 26384 "region": "Capitale-Nationale",
26385 26385 "postal_prefix": "G3Z",
@@ -26403,10 +26403,10 @@
26403 26403 "https://www.tourisme-charlevoix.com/fr/entreprises/centre-sante-beaute-francine-thibeault"
26404 26404 ],
26405 26405 "language": "fr",
26406 − "ecommerce": false,
26406 + "ecommerce": true,
26407 26407 "verification_date": "2026-08-12",
26408 26408 "status": "verified",
26409 − "enabled": false,
26409 + "enabled": true,
26410 26410 "last_reprobe": "2026-08-19",
26411 26411 "geo": {
26412 26412 "lat": 47.4454,
@@ -27318,8 +27318,8 @@
27318 27318 "id": "champdelfes.com",
27319 27319 "name": "Champ d'elfes",
27320 27320 "url": "https://champdelfes.com",
27321 − "platform": "",
27322 − "catalog_endpoint": "",
27321 + "platform": "votresite",
27322 + "catalog_endpoint": "/boutique",
27323 27323 "city": "",
27324 27324 "region": "",
27325 27325 "postal_prefix": null,
@@ -27341,7 +27341,7 @@
27341 27341 "ecommerce": true,
27342 27342 "verification_date": "2026-08-12",
27343 27343 "status": "probable",
27344 − "enabled": false,
27344 + "enabled": true,
27345 27345 "last_reprobe": "2026-08-19"
27346 27346 },
27347 27347 {
@@ -27999,8 +27999,8 @@
27999 27999 "id": "charlevoixpurelaine.ca",
28000 28000 "name": "Charlevoix Pure laine - CMAQ",
28001 28001 "url": "https://charlevoixpurelaine.ca",
28002 − "platform": "",
28003 − "catalog_endpoint": "",
28002 + "platform": "votresite",
28003 + "catalog_endpoint": "/boutique",
28004 28004 "city": "",
28005 28005 "region": "Côte-Nord",
28006 28006 "postal_prefix": "G0T",
@@ -28026,10 +28026,10 @@
28026 28026 "Charlevoix pure laine Yvan Delage tricoteur québec"
28027 28027 ],
28028 28028 "language": "fr",
28029 − "ecommerce": false,
28029 + "ecommerce": true,
28030 28030 "verification_date": "2026-08-12",
28031 28031 "status": "verified",
28032 − "enabled": false,
28032 + "enabled": true,
28033 28033 "last_reprobe": "2026-08-19",
28034 28034 "geo": {
28035 28035 "lat": 47.6525,
@@ -31179,8 +31179,8 @@
31179 31179 "id": "closdespetitsbergers.ca",
31180 31180 "name": "Clos des Petits Bergers",
31181 31181 "url": "https://closdespetitsbergers.ca",
31182 − "platform": "",
31183 − "catalog_endpoint": "",
31182 + "platform": "votresite",
31183 + "catalog_endpoint": "/boutique",
31184 31184 "city": "",
31185 31185 "region": "Centre-du-Québec",
31186 31186 "postal_prefix": "J0C",
@@ -31206,10 +31206,10 @@
31206 31206 "https://goutezy.com/entreprise/clos-des-petits-bergers/"
31207 31207 ],
31208 31208 "language": "fr",
31209 − "ecommerce": false,
31209 + "ecommerce": true,
31210 31210 "verification_date": "2026-08-12",
31211 31211 "status": "probable",
31212 − "enabled": false,
31212 + "enabled": true,
31213 31213 "last_reprobe": "2026-08-18",
31214 31214 "geo": {
31215 31215 "lat": 45.9914,
@@ -32476,8 +32476,8 @@
32476 32476 "id": "concepterable.ca",
32477 32477 "name": "Conceptérable inc.",
32478 32478 "url": "https://concepterable.ca",
32479 − "platform": "",
32480 − "catalog_endpoint": "",
32479 + "platform": "votresite",
32480 + "catalog_endpoint": "/produits",
32481 32481 "city": "",
32482 32482 "region": "Capitale-Nationale",
32483 32483 "postal_prefix": "G0A",
@@ -32501,10 +32501,10 @@
32501 32501 "https://www.erabledici.ca/fr/erabliere/concepterable-inc/"
32502 32502 ],
32503 32503 "language": "fr",
32504 − "ecommerce": false,
32504 + "ecommerce": true,
32505 32505 "verification_date": "2026-08-12",
32506 32506 "status": "probable",
32507 − "enabled": false,
32507 + "enabled": true,
32508 32508 "last_reprobe": "2026-08-18",
32509 32509 "geo": {
32510 32510 "lat": 46.8524,
@@ -38028,8 +38028,8 @@
38028 38028 "id": "metamorphoseonaturel.ca",
38029 38029 "name": "Délices Sublimes",
38030 38030 "url": "https://metamorphoseonaturel.ca",
38031 − "platform": "",
38032 − "catalog_endpoint": "",
38031 + "platform": "votresite",
38032 + "catalog_endpoint": "/boutique",
38033 38033 "city": "",
38034 38034 "region": "Outaouais",
38035 38035 "postal_prefix": "J8V",
@@ -38056,7 +38056,7 @@
38056 38056 "ecommerce": true,
38057 38057 "verification_date": "2026-08-12",
38058 38058 "status": "verified",
38059 − "enabled": false,
38059 + "enabled": true,
38060 38060 "last_reprobe": "2026-08-19",
38061 38061 "geo": {
38062 38062 "lat": 45.488,
@@ -40628,8 +40628,8 @@
40628 40628 "id": "domainecotedunord.com",
40629 40629 "name": "Domaine Côte du Nord",
40630 40630 "url": "https://domainecotedunord.com",
40631 − "platform": "",
40632 − "catalog_endpoint": "",
40631 + "platform": "votresite",
40632 + "catalog_endpoint": "/boutique",
40633 40633 "city": "",
40634 40634 "region": "Côte-Nord",
40635 40635 "postal_prefix": "G0H",
@@ -40655,7 +40655,7 @@
40655 40655 "ecommerce": true,
40656 40656 "verification_date": "2026-08-12",
40657 40657 "status": "probable",
40658 − "enabled": false,
40658 + "enabled": true,
40659 40659 "last_reprobe": "2026-08-18",
40660 40660 "geo": {
40661 40661 "lat": 49.1633,
@@ -41631,8 +41631,8 @@
41631 41631 "id": "domainelacharmante.com",
41632 41632 "name": "Domaine La Charmante",
41633 41633 "url": "https://domainelacharmante.com",
41634 − "platform": "",
41635 − "catalog_endpoint": "",
41634 + "platform": "votresite",
41635 + "catalog_endpoint": "/boutique",
41636 41636 "city": "",
41637 41637 "region": "Chaudière-Appalaches",
41638 41638 "postal_prefix": "G0R",
@@ -41656,10 +41656,10 @@
41656 41656 "https://arretsgourmands.ca/arrets-gourmands/domaine-la-charmante"
41657 41657 ],
41658 41658 "language": "fr",
41659 − "ecommerce": false,
41659 + "ecommerce": true,
41660 41660 "verification_date": "2026-08-12",
41661 41661 "status": "probable",
41662 − "enabled": false,
41662 + "enabled": true,
41663 41663 "last_reprobe": "2026-08-18",
41664 41664 "geo": {
41665 41665 "lat": 46.9055,
@@ -41763,8 +41763,8 @@
41763 41763 "id": "domaineloreedesbois.ca",
41764 41764 "name": "Domaine L’Orée des Bois",
41765 41765 "url": "https://domaineloreedesbois.ca",
41766 − "platform": "",
41767 − "catalog_endpoint": "",
41766 + "platform": "votresite",
41767 + "catalog_endpoint": "/boutique",
41768 41768 "city": "",
41769 41769 "region": "Saguenay–Lac-Saint-Jean",
41770 41770 "postal_prefix": "G0W",
@@ -41788,10 +41788,10 @@
41788 41788 "https://zoneboreale.com/entreprises/domaine-loree-des-bois/"
41789 41789 ],
41790 41790 "language": "fr",
41791 − "ecommerce": false,
41791 + "ecommerce": true,
41792 41792 "verification_date": "2026-08-12",
41793 41793 "status": "verified",
41794 − "enabled": false,
41794 + "enabled": true,
41795 41795 "last_reprobe": "2026-08-18",
41796 41796 "geo": {
41797 41797 "lat": 48.8854,
@@ -45996,8 +45996,8 @@
45996 45996 "id": "erablieredulactaureau.com",
45997 45997 "name": "Érablière du Lac Taureau",
45998 45998 "url": "https://erablieredulactaureau.com",
45999 − "platform": "",
46000 − "catalog_endpoint": "",
45999 + "platform": "votresite",
46000 + "catalog_endpoint": "/boutique",
46001 46001 "city": "",
46002 46002 "region": "Lanaudière",
46003 46003 "postal_prefix": "J0K",
@@ -46024,7 +46024,7 @@
46024 46024 "ecommerce": true,
46025 46025 "verification_date": "2026-08-12",
46026 46026 "status": "probable",
46027 − "enabled": false,
46027 + "enabled": true,
46028 46028 "last_reprobe": "2026-08-18",
46029 46029 "geo": {
46030 46030 "lat": 46.104,
@@ -66916,8 +66916,8 @@
66916 66916 "id": "imatech-moore.com",
66917 66917 "name": "Imatech-Moore",
66918 66918 "url": "https://imatech-moore.com",
66919 − "platform": "",
66920 − "catalog_endpoint": "",
66919 + "platform": "votresite",
66920 + "catalog_endpoint": "/boutique",
66921 66921 "city": "",
66922 66922 "region": "Centre-du-Québec",
66923 66923 "postal_prefix": "G6P",
@@ -66939,10 +66939,10 @@
66939 66939 "https://lesproduitsduquebec.com/entreprises-adherentes/imatech-moore"
66940 66940 ],
66941 66941 "language": "fr",
66942 − "ecommerce": false,
66942 + "ecommerce": true,
66943 66943 "verification_date": "2026-08-12",
66944 66944 "status": "verified",
66945 − "enabled": false,
66945 + "enabled": true,
66946 66946 "last_reprobe": "2026-08-18",
66947 66947 "geo": {
66948 66948 "lat": 46.0606,
@@ -68456,8 +68456,8 @@
68456 68456 "id": "jardinschantdevie.com",
68457 68457 "name": "Jardins Chant de Vie - Goûtez-y!",
68458 68458 "url": "https://jardinschantdevie.com",
68459 − "platform": "",
68460 − "catalog_endpoint": "",
68459 + "platform": "votresite",
68460 + "catalog_endpoint": "/boutique",
68461 68461 "city": "",
68462 68462 "region": "Centre-du-Québec",
68463 68463 "postal_prefix": "J0B",
@@ -68481,10 +68481,10 @@
68481 68481 "https://goutezy.com/entreprise/jardins-chant-de-vie/"
68482 68482 ],
68483 68483 "language": "fr",
68484 − "ecommerce": false,
68484 + "ecommerce": true,
68485 68485 "verification_date": "2026-08-12",
68486 68486 "status": "verified",
68487 − "enabled": false,
68487 + "enabled": true,
68488 68488 "last_reprobe": "2026-08-19",
68489 68489 "geo": {
68490 68490 "lat": 45.242,
@@ -77266,8 +77266,8 @@
77266 77266 "id": "lamanchure.com",
77267 77267 "name": "LaManchure",
77268 77268 "url": "https://lamanchure.com",
77269 − "platform": "",
77270 − "catalog_endpoint": "",
77269 + "platform": "votresite",
77270 + "catalog_endpoint": "/boutique",
77271 77271 "city": "",
77272 77272 "region": "",
77273 77273 "postal_prefix": null,
@@ -77289,7 +77289,7 @@
77289 77289 "ecommerce": true,
77290 77290 "verification_date": "2026-08-12",
77291 77291 "status": "probable",
77292 − "enabled": false,
77292 + "enabled": true,
77293 77293 "last_reprobe": "2026-08-19"
77294 77294 },
77295 77295 {
@@ -82336,8 +82336,8 @@
82336 82336 "id": "lemieldabee.ca",
82337 82337 "name": "Créateurs",
82338 82338 "url": "https://lemieldabee.ca",
82339 − "platform": "",
82340 − "catalog_endpoint": "",
82339 + "platform": "votresite",
82340 + "catalog_endpoint": "/boutique",
82341 82341 "city": "",
82342 82342 "region": "Estrie",
82343 82343 "postal_prefix": "J1E",
@@ -82361,10 +82361,10 @@
82361 82361 "https://createursdesaveurs.com/createurs/le-miel-dabee/"
82362 82362 ],
82363 82363 "language": "fr",
82364 − "ecommerce": false,
82364 + "ecommerce": true,
82365 82365 "verification_date": "2026-08-12",
82366 82366 "status": "verified",
82367 − "enabled": false,
82367 + "enabled": true,
82368 82368 "last_reprobe": "2026-08-19",
82369 82369 "geo": {
82370 82370 "lat": 45.4301,
@@ -82617,8 +82617,8 @@
82617 82617 "id": "lemoussonneur.ca",
82618 82618 "name": "Le Moussonneur",
82619 82619 "url": "https://lemoussonneur.ca",
82620 − "platform": "",
82621 − "catalog_endpoint": "",
82620 + "platform": "votresite",
82621 + "catalog_endpoint": "/produits",
82622 82622 "city": "",
82623 82623 "region": "Bas-Saint-Laurent",
82624 82624 "postal_prefix": null,
@@ -82640,7 +82640,7 @@
82640 82640 "ecommerce": true,
82641 82641 "verification_date": "2026-08-12",
82642 82642 "status": "probable",
82643 − "enabled": false,
82643 + "enabled": true,
82644 82644 "last_reprobe": "2026-08-19"
82645 82645 },
82646 82646 {
@@ -84587,8 +84587,8 @@
84587 84587 "id": "lesappeauxdusaintlaurent.com",
84588 84588 "name": "Les appeaux du Saint-Laurent - CMAQ",
84589 84589 "url": "https://lesappeauxdusaintlaurent.com",
84590 − "platform": "",
84591 − "catalog_endpoint": "",
84590 + "platform": "votresite",
84591 + "catalog_endpoint": "/boutique",
84592 84592 "city": "",
84593 84593 "region": "",
84594 84594 "postal_prefix": "G6V",
@@ -84613,7 +84613,7 @@
84613 84613 "ecommerce": true,
84614 84614 "verification_date": "2026-08-12",
84615 84615 "status": "verified",
84616 − "enabled": false,
84616 + "enabled": true,
84617 84617 "last_reprobe": "2026-08-19",
84618 84618 "geo": {
84619 84619 "lat": 46.8207,
@@ -86872,8 +86872,8 @@
86872 86872 "id": "lesjardinsrevertere.ca",
86873 86873 "name": "Les Jardins Revertere S.E.N.C.",
86874 86874 "url": "https://lesjardinsrevertere.ca",
86875 − "platform": "",
86876 − "catalog_endpoint": "",
86875 + "platform": "votresite",
86876 + "catalog_endpoint": "/boutique",
86877 86877 "city": "",
86878 86878 "region": "Estrie",
86879 86879 "postal_prefix": "J0B",
@@ -86902,7 +86902,7 @@
86902 86902 "ecommerce": true,
86903 86903 "verification_date": "2026-08-12",
86904 86904 "status": "probable",
86905 − "enabled": false,
86905 + "enabled": true,
86906 86906 "last_reprobe": "2026-08-19",
86907 86907 "geo": {
86908 86908 "lat": 45.242,
@@ -96495,8 +96495,8 @@
96495 96495 "id": "merlaine.com",
96496 96496 "name": "Merlaine",
96497 96497 "url": "https://merlaine.com",
96498 − "platform": "",
96499 − "catalog_endpoint": "",
96498 + "platform": "votresite",
96499 + "catalog_endpoint": "/boutique",
96500 96500 "city": "",
96501 96501 "region": "",
96502 96502 "postal_prefix": null,
@@ -96516,7 +96516,7 @@
96516 96516 "ecommerce": true,
96517 96517 "verification_date": "2026-08-12",
96518 96518 "status": "probable",
96519 − "enabled": false,
96519 + "enabled": true,
96520 96520 "last_reprobe": "2026-08-19"
96521 96521 },
96522 96522 {
@@ -96912,8 +96912,8 @@
96912 96912 "id": "michelecourtemanche.ca",
96913 96913 "name": "Michèle Courtemanche, artiste bijoutière - CMAQ",
96914 96914 "url": "https://michelecourtemanche.ca",
96915 − "platform": "",
96916 − "catalog_endpoint": "",
96915 + "platform": "votresite",
96916 + "catalog_endpoint": "/boutique",
96917 96917 "city": "",
96918 96918 "region": "Outaouais",
96919 96919 "postal_prefix": "J8Y",
@@ -96938,7 +96938,7 @@
96938 96938 "ecommerce": true,
96939 96939 "verification_date": "2026-08-12",
96940 96940 "status": "verified",
96941 − "enabled": false,
96941 + "enabled": true,
96942 96942 "last_reprobe": "2026-08-19",
96943 96943 "geo": {
96944 96944 "lat": 45.4603,
@@ -99590,8 +99590,8 @@
99590 99590 "id": "mlatelierdecouture.com",
99591 99591 "name": "M l’atelier de couture - CMAQ",
99592 99592 "url": "https://mlatelierdecouture.com",
99593 − "platform": "",
99594 − "catalog_endpoint": "",
99593 + "platform": "votresite",
99594 + "catalog_endpoint": "/boutique",
99595 99595 "city": "",
99596 99596 "region": "Chaudière-Appalaches",
99597 99597 "postal_prefix": "G0N",
@@ -99616,7 +99616,7 @@
99616 99616 "ecommerce": true,
99617 99617 "verification_date": "2026-08-12",
99618 99618 "status": "verified",
99619 − "enabled": false,
99619 + "enabled": true,
99620 99620 "last_reprobe": "2026-08-19",
99621 99621 "geo": {
99622 99622 "lat": 46.0651,
@@ -100206,8 +100206,8 @@
100206 100206 "id": "monasteredebethleem.ca",
100207 100207 "name": "Les Moniales de Bethléem - CMAQ",
100208 100208 "url": "https://monasteredebethleem.ca",
100209 − "platform": "",
100210 − "catalog_endpoint": "",
100209 + "platform": "votresite",
100210 + "catalog_endpoint": "/boutique",
100211 100211 "city": "",
100212 100212 "region": "Lanaudière",
100213 100213 "postal_prefix": "J0K",
@@ -100232,7 +100232,7 @@
100232 100232 "ecommerce": true,
100233 100233 "verification_date": "2026-08-12",
100234 100234 "status": "verified",
100235 − "enabled": false,
100235 + "enabled": true,
100236 100236 "last_reprobe": "2026-08-19",
100237 100237 "geo": {
100238 100238 "lat": 46.104,
@@ -110027,8 +110027,8 @@
110027 110027 "id": "patelin.ca",
110028 110028 "name": "Les produits Patelin",
110029 110029 "url": "https://patelin.ca",
110030 − "platform": "",
110031 − "catalog_endpoint": "",
110030 + "platform": "votresite",
110031 + "catalog_endpoint": "/boutique",
110032 110032 "city": "",
110033 110033 "region": "Chaudière-Appalaches",
110034 110034 "postal_prefix": "G0R",
@@ -110052,10 +110052,10 @@
110052 110052 "https://alimentsduquebec.com/entreprises/les-produits-patelin"
110053 110053 ],
110054 110054 "language": "fr",
110055 − "ecommerce": false,
110055 + "ecommerce": true,
110056 110056 "verification_date": "2026-08-12",
110057 110057 "status": "verified",
110058 − "enabled": false,
110058 + "enabled": true,
110059 110059 "last_reprobe": "2026-08-19",
110060 110060 "geo": {
110061 110061 "lat": 46.9055,
@@ -110920,8 +110920,8 @@
110920 110920 "id": "penelopeclinique.com",
110921 110921 "name": "Pénélope Clinique",
110922 110922 "url": "https://penelopeclinique.com",
110923 − "platform": "",
110924 − "catalog_endpoint": "",
110923 + "platform": "votresite",
110924 + "catalog_endpoint": "/boutique",
110925 110925 "city": "",
110926 110926 "region": "Laurentides",
110927 110927 "postal_prefix": "J7Z",
@@ -110943,10 +110943,10 @@
110943 110943 "piercing body jewelry Québec boutique en ligne"
110944 110944 ],
110945 110945 "language": "fr",
110946 − "ecommerce": false,
110946 + "ecommerce": true,
110947 110947 "verification_date": "2026-08-12",
110948 110948 "status": "probable",
110949 − "enabled": false,
110949 + "enabled": true,
110950 110950 "last_reprobe": "2026-08-19",
110951 110951 "geo": {
110952 110952 "lat": 45.795,
@@ -122590,8 +122590,8 @@
122590 122590 "id": "savonneriedemartigny.ca",
122591 122591 "name": "Savonnerie de Martigny",
122592 122592 "url": "https://savonneriedemartigny.ca",
122593 − "platform": "",
122594 − "catalog_endpoint": "",
122593 + "platform": "votresite",
122594 + "catalog_endpoint": "/boutique",
122595 122595 "city": "",
122596 122596 "region": "",
122597 122597 "postal_prefix": null,
@@ -122614,7 +122614,7 @@
122614 122614 "ecommerce": true,
122615 122615 "verification_date": "2026-08-12",
122616 122616 "status": "probable",
122617 − "enabled": false,
122617 + "enabled": true,
122618 122618 "last_reprobe": "2026-08-19"
122619 122619 },
122620 122620 {
@@ -124072,8 +124072,8 @@
124072 124072 "id": "serreslouiseturcotte.com",
124073 124073 "name": "Serres Louise Turcotte",
124074 124074 "url": "https://serreslouiseturcotte.com",
124075 − "platform": "",
124076 − "catalog_endpoint": "",
124075 + "platform": "votresite",
124076 + "catalog_endpoint": "/boutique",
124077 124077 "city": "",
124078 124078 "region": "Saguenay–Lac-Saint-Jean",
124079 124079 "postal_prefix": "G0V",
@@ -124100,7 +124100,7 @@
124100 124100 "ecommerce": true,
124101 124101 "verification_date": "2026-08-12",
124102 124102 "status": "probable",
124103 − "enabled": false,
124103 + "enabled": true,
124104 124104 "last_reprobe": "2026-08-19",
124105 124105 "geo": {
124106 124106 "lat": 48.3448,
@@ -127421,8 +127421,8 @@
127421 127421 "id": "sucredorgedantan.com",
127422 127422 "name": "Sucre D'orge D'antan inc.",
127423 127423 "url": "https://sucredorgedantan.com",
127424 − "platform": "",
127425 − "catalog_endpoint": "",
127424 + "platform": "votresite",
127425 + "catalog_endpoint": "/boutique",
127426 127426 "city": "",
127427 127427 "region": "Estrie",
127428 127428 "postal_prefix": "J0B",
@@ -127449,7 +127449,7 @@
127449 127449 "ecommerce": true,
127450 127450 "verification_date": "2026-08-12",
127451 127451 "status": "verified",
127452 − "enabled": false,
127452 + "enabled": true,
127453 127453 "last_reprobe": "2026-08-19",
127454 127454 "geo": {
127455 127455 "lat": 45.242,
@@ -131239,8 +131239,8 @@
131239 131239 "id": "tresorsdesbois2.com",
131240 131240 "name": "Trésors des Bois",
131241 131241 "url": "https://tresorsdesbois2.com",
131242 − "platform": "",
131243 − "catalog_endpoint": "",
131242 + "platform": "votresite",
131243 + "catalog_endpoint": "/boutique",
131244 131244 "city": "",
131245 131245 "region": "Côte-Nord",
131246 131246 "postal_prefix": null,
@@ -131260,7 +131260,7 @@
131260 131260 "ecommerce": true,
131261 131261 "verification_date": "2026-08-12",
131262 131262 "status": "probable",
131263 − "enabled": false,
131263 + "enabled": true,
131264 131264 "last_reprobe": "2026-08-19"
131265 131265 },
131266 131266 {
@@ -133444,8 +133444,8 @@
133444 133444 "id": "varin.ca",
133445 133445 "name": "Érablière Varin",
133446 133446 "url": "https://varin.ca",
133447 − "platform": "",
133448 − "catalog_endpoint": "",
133447 + "platform": "votresite",
133448 + "catalog_endpoint": "/boutique",
133449 133449 "city": "",
133450 133450 "region": "Laurentides",
133451 133451 "postal_prefix": "J0N",
@@ -133469,10 +133469,10 @@
133469 133469 "https://www.erabledici.ca/fr/erabliere/erabliere-varin/"
133470 133470 ],
133471 133471 "language": "fr",
133472 − "ecommerce": false,
133472 + "ecommerce": true,
133473 133473 "verification_date": "2026-08-12",
133474 133474 "status": "verified",
133475 − "enabled": false,
133475 + "enabled": true,
133476 133476 "last_reprobe": "2026-08-19",
133477 133477 "geo": {
133478 133478 "lat": 45.718,
@@ -137007,8 +137007,8 @@
137007 137007 "id": "vivelesepices.com",
137008 137008 "name": "Vive les Épices",
137009 137009 "url": "https://vivelesepices.com",
137010 − "platform": "",
137011 − "catalog_endpoint": "",
137010 + "platform": "votresite",
137011 + "catalog_endpoint": "/boutique",
137012 137012 "city": "",
137013 137013 "region": "Estrie",
137014 137014 "postal_prefix": "J1N",
@@ -137035,7 +137035,7 @@
137035 137035 "ecommerce": true,
137036 137036 "verification_date": "2026-08-12",
137037 137037 "status": "probable",
137038 − "enabled": false,
137038 + "enabled": true,
137039 137039 "last_reprobe": "2026-08-19",
137040 137040 "geo": {
137041 137041 "lat": 45.3814,
@@ -138896,8 +138896,8 @@
138896 138896 "id": "zylverybijouxdesign.com",
138897 138897 "name": "Zylvery-Bijoux Design",
138898 138898 "url": "https://zylverybijouxdesign.com",
138899 − "platform": "",
138900 − "catalog_endpoint": "",
138899 + "platform": "votresite",
138900 + "catalog_endpoint": "/boutique",
138901 138901 "city": "",
138902 138902 "region": "",
138903 138903 "postal_prefix": null,
@@ -138922,7 +138922,7 @@
138922 138922 "ecommerce": true,
138923 138923 "verification_date": "2026-08-12",
138924 138924 "status": "verified",
138925 − "enabled": false,
138925 + "enabled": true,
138926 138926 "last_reprobe": "2026-08-19"
138927 138927 },
138928 138928 {
@@ -152521,8 +152521,8 @@
152521 152521 "id": "bouetteetbrouette.ca",
152522 152522 "name": "Bouette & Brouette",
152523 152523 "url": "https://bouetteetbrouette.ca",
152524 − "platform": "",
152525 − "catalog_endpoint": "",
152524 + "platform": "votresite",
152525 + "catalog_endpoint": "/produits",
152526 152526 "city": "",
152527 152527 "region": "Montérégie",
152528 152528 "postal_prefix": "J0J",
@@ -152545,7 +152545,7 @@
152545 152545 "ecommerce": true,
152546 152546 "verification_date": "2026-08-19",
152547 152547 "status": "probable",
152548 − "enabled": false,
152548 + "enabled": true,
152549 152549 "certifications": [
152550 152550 {
152551 152551 "label": "Biologique — CARTV",
@@ -154813,8 +154813,8 @@
154813 154813 "id": "degermeenpousse.com",
154814 154814 "name": "De Germe en Pousse",
154815 154815 "url": "https://degermeenpousse.com",
154816 − "platform": "",
154817 − "catalog_endpoint": "",
154816 + "platform": "votresite",
154817 + "catalog_endpoint": "/boutique",
154818 154818 "city": "",
154819 154819 "region": "Laurentides",
154820 154820 "postal_prefix": "J7N",
@@ -154834,7 +154834,7 @@
154834 154834 "ecommerce": true,
154835 154835 "verification_date": "2026-08-19",
154836 154836 "status": "probable",
154837 − "enabled": false,
154837 + "enabled": true,
154838 154838 "certifications": [
154839 154839 {
154840 154840 "label": "Biologique — CARTV",
@@ -157031,8 +157031,8 @@
157031 157031 "id": "fermelabonte.com",
157032 157032 "name": "Ferme Labonté et Filles",
157033 157033 "url": "https://fermelabonte.com",
157034 − "platform": "",
157035 − "catalog_endpoint": "",
157034 + "platform": "votresite",
157035 + "catalog_endpoint": "/boutique",
157036 157036 "city": "",
157037 157037 "region": "Chaudière-Appalaches",
157038 157038 "postal_prefix": "G0S",
@@ -157051,10 +157051,10 @@
157051 157051 "http://www.produitsbioquebec.info/interroGrandPublicFr.do"
157052 157052 ],
157053 157053 "language": "fr",
157054 − "ecommerce": false,
157054 + "ecommerce": true,
157055 157055 "verification_date": "2026-08-19",
157056 157056 "status": "verified",
157057 − "enabled": false,
157057 + "enabled": true,
157058 157058 "certifications": [
157059 157059 {
157060 157060 "label": "Biologique — CARTV",
@@ -158849,8 +158849,8 @@
158849 158849 "id": "houblonsfranklin.com",
158850 158850 "name": "Houblons Franklin",
158851 158851 "url": "https://houblonsfranklin.com",
158852 − "platform": "",
158853 − "catalog_endpoint": "",
158852 + "platform": "votresite",
158853 + "catalog_endpoint": "/produits",
158854 158854 "city": "",
158855 158855 "region": "Montérégie",
158856 158856 "postal_prefix": "JOS",
@@ -158869,10 +158869,10 @@
158869 158869 "http://www.produitsbioquebec.info/interroGrandPublicFr.do"
158870 158870 ],
158871 158871 "language": "fr",
158872 − "ecommerce": false,
158872 + "ecommerce": true,
158873 158873 "verification_date": "2026-08-19",
158874 158874 "status": "probable",
158875 − "enabled": false,
158875 + "enabled": true,
158876 158876 "certifications": [
158877 158877 {
158878 158878 "label": "Biologique — CARTV",
@@ -162138,8 +162138,8 @@
162138 162138 "id": "lejardindesvioloneux.ca",
162139 162139 "name": "Édith Baragar DBA Le Jardin des Violoneux",
162140 162140 "url": "https://lejardindesvioloneux.ca",
162141 − "platform": "",
162142 − "catalog_endpoint": "",
162141 + "platform": "votresite",
162142 + "catalog_endpoint": "/boutique",
162143 162143 "city": "",
162144 162144 "region": "Montérégie",
162145 162145 "postal_prefix": "J0H",
@@ -162156,10 +162156,10 @@
162156 162156 "http://www.produitsbioquebec.info/interroGrandPublicFr.do"
162157 162157 ],
162158 162158 "language": "fr",
162159 − "ecommerce": false,
162159 + "ecommerce": true,
162160 162160 "verification_date": "2026-08-19",
162161 162161 "status": "verified",
162162 − "enabled": false,
162162 + "enabled": true,
162163 162163 "certifications": [
162164 162164 {
162165 162165 "label": "Biologique — CARTV",
@@ -162426,8 +162426,8 @@
162426 162426 "id": "lesfantaisiesdelerable.ca",
162427 162427 "name": "Marc Carignan enr.",
162428 162428 "url": "https://lesfantaisiesdelerable.ca",
162429 − "platform": "",
162430 − "catalog_endpoint": "",
162429 + "platform": "votresite",
162430 + "catalog_endpoint": "/boutique",
162431 162431 "city": "",
162432 162432 "region": "Montérégie",
162433 162433 "postal_prefix": "J7W",
@@ -162447,7 +162447,7 @@
162447 162447 "ecommerce": true,
162448 162448 "verification_date": "2026-08-19",
162449 162449 "status": "probable",
162450 − "enabled": false,
162450 + "enabled": true,
162451 162451 "certifications": [
162452 162452 {
162453 162453 "label": "Biologique — CARTV",
@@ -163210,8 +163210,8 @@
163210 163210 "id": "manoverde.ca",
163211 163211 "name": "Mano Verde",
163212 163212 "url": "https://manoverde.ca",
163213 − "platform": "",
163214 − "catalog_endpoint": "",
163213 + "platform": "votresite",
163214 + "catalog_endpoint": "/boutique",
163215 163215 "city": "",
163216 163216 "region": "",
163217 163217 "postal_prefix": null,
@@ -163234,7 +163234,7 @@
163234 163234 "ecommerce": true,
163235 163235 "verification_date": "2026-08-19",
163236 163236 "status": "verified",
163237 − "enabled": false
163237 + "enabled": true
163238 163238 },
163239 163239 {
163240 163240 "id": "mapleleaffoods.com",
@@ -172841,8 +172841,8 @@
172841 172841 "id": "paraventsdesign.com",
172842 172842 "name": "Design",
172843 172843 "url": "https://paraventsdesign.com",
172844 − "platform": "",
172845 − "catalog_endpoint": "",
172844 + "platform": "votresite",
172845 + "catalog_endpoint": "/boutique",
172846 172846 "city": "",
172847 172847 "region": "Lanaudière",
172848 172848 "postal_prefix": "J0K",
@@ -172866,7 +172866,7 @@
172866 172866 "ecommerce": true,
172867 172867 "verification_date": "2026-08-21",
172868 172868 "status": "verified",
172869 − "enabled": false,
172869 + "enabled": true,
172870 172870 "geo": {
172871 172871 "lat": 46.104,
172872 172872 "lng": -73.256,
@@ -173767,4 +173767,4 @@
173767 173767 }
173768 173768 }
173769 173769 ]
173770 −}
173770 +}
\ No newline at end of file
modified docs/connecteurs/INDEX.md +25 −24
@@ -1,21 +1,22 @@
1 1 # Fabri-Ka — Connecteurs (documentation standardisée)
2 2
3 −*Généré le 2026-08-19 03:40 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
3 +*Généré le 2026-08-23 15:39 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
4 4
5 −**3507 boutiques** au registre (`data/stores.json`, généré le 2026-08-18), **1 570** activées en base, **300 526 produits actifs**. Un connecteur par PLATEFORME e-commerce (dispatch `fabrika/connectors/__init__.py`), plus un transport de secours Scrapfly et deux pipelines transverses (découverte/registre, enrichissement).
5 +**4082 boutiques** au registre (`data/stores.json`, généré le 2026-08-21), **1 701** activées en base, **361 215 produits actifs**. Un connecteur par PLATEFORME e-commerce (dispatch `fabrika/connectors/__init__.py`), plus un transport de secours Scrapfly et deux pipelines transverses (découverte/registre, enrichissement).
6 6
7 7 ## Connecteurs-plateformes
8 8
9 9 | Connecteur | Fiche | Boutiques (registre) | Avec produits | Produits actifs | Prix | Photos | Détails |
10 10 |---|---|---|---|---|---|---|---|
11 −| Connecteur Shopify | [shopify](shopify.md) | 702 | 642 | 207 187 | 99.2 % | 96.5 % | 100.0 % |
12 −| Connecteur WooCommerce (Store API) | [woocommerce](woocommerce.md) | 1320 | 442 | 74 048 | 94.0 % | 71.8 % | 86.6 % |
13 −| Connecteur Wix Stores | [wix](wix.md) | 339 | 197 | 7 423 | 97.0 % | 98.6 % | 97.9 % |
14 −| Connecteur Squarespace | [squarespace](squarespace.md) | 128 | 23 | 803 | 100.0 % | 99.6 % | 0.0 % |
15 −| Connecteur Square Online | [square](square.md) | 56 | 36 | 2 833 | 99.7 % | 92.5 % | 100.0 % |
16 −| Connecteur générique (JSON-LD / microdata / OG) | [generic](generic.md) | 74 | 23 | 8 232 | 100.0 % | 82.8 % | 0.0 % |
11 +| Connecteur Shopify | [shopify](shopify.md) | 763 | 694 | 244 732 | 99.3 % | 96.8 % | 100.0 % |
12 +| Connecteur WooCommerce (Store API) | [woocommerce](woocommerce.md) | 1556 | 509 | 92 521 | 86.4 % | 71.5 % | 87.8 % |
13 +| Connecteur Wix Stores | [wix](wix.md) | 393 | 240 | 8 924 | 97.1 % | 98.5 % | 97.5 % |
14 +| Connecteur Squarespace | [squarespace](squarespace.md) | 157 | 23 | 788 | 100.0 % | 99.6 % | 0.0 % |
15 +| Connecteur Square Online | [square](square.md) | 68 | 36 | 2 832 | 99.7 % | 92.5 % | 100.0 % |
16 +| Connecteur Votresite.ca (Drupal + OpenCart) | [votresite](votresite.md) | 45 | 43 | 3 190 | 95.5 % | 100.0 % | 100.0 % |
17 +| Connecteur générique (JSON-LD / microdata / OG) | [generic](generic.md) | 81 | 23 | 8 228 | 100.0 % | 82.8 % | 0.0 % |
17 18 | Transport Scrapfly | [scrapfly-transport](scrapfly-transport.md) | — | — | — | — | — | — |
18 −| Ecwid (verdict : non couvert) | [ecwid](ecwid.md) | 15 | 0 | 0 | — | — | — |
19 +| Ecwid (verdict : non couvert) | [ecwid](ecwid.md) | 19 | 0 | 0 | — | — | — |
19 20
20 21 Pipelines transverses : [découverte & registre](decouverte-registre.md) · [enrichissement boutiques](enrichissement-boutiques.md).
21 22
@@ -23,21 +24,21 @@ Pipelines transverses : [découverte & registre](decouverte-registre.md) · [enr
23 24
24 25 | Boutique | Domaine | Plateforme | Produits | Dernier sync |
25 26 |---|---|---|---|---|
26 −| Ici & Là - T-shirts et Souvenirs des régions - Acheter québécois | `ici-la.co` | shopify | 20 075 | 2026-08-19 02:27 |
27 −| GAGNON - La Grande Quincaillerie | `gagnonlgq.com` | shopify | 19 516 | 2026-08-19 02:16 |
28 −| Pieces de remorques et accessoires - Acheter québécois | `remorquetrailer.com` | woocommerce | 19 358 | 2026-08-19 03:23 |
29 −| La Maison du Bleuet | `lamaisondubleuet.com` | shopify | 8 629 | 2026-08-19 02:36 |
30 −| Bijouterie Jodoin | `bijouteriejodoin.com` | shopify | 8 252 | 2026-08-19 01:24 |
31 −| Oberson | `oberson.com` | shopify | 7 419 | 2026-08-19 03:14 |
32 −| Coopérative La Manne - Goûtez-y! | `cooplamanne.com` | woocommerce | 7 216 | 2026-08-19 01:48 |
33 −| LilloJEUX | `lillojeux.ca` | woocommerce | 6 590 | 2026-08-19 02:50 |
34 −| Paperole | `paperole.com` | shopify | 4 946 | 2026-08-19 03:15 |
35 −| Veille sur toi Inc. - CMAQ | `veillesurtoi.com` | shopify | 4 431 | 2026-08-18 22:07 |
36 −| Chic Placard | `chicplacard.ca` | shopify | 4 420 | 2026-08-19 01:43 |
37 −| Bijoux Medusa | `bijouxmedusa.com` | shopify | 3 794 | 2026-08-19 01:25 |
38 −| Les Ptits Mosüs (Alice et Simone) | `lesptitsmosus.com` | shopify | 3 396 | 2026-08-19 02:46 |
39 −| Poches & Fils | `pochesetfils.com` | shopify | 3 238 | 2026-08-19 03:16 |
40 −| Biscotte Yarns | `biscotteyarns.com` | shopify | 3 194 | 2026-08-19 01:26 |
27 +| Ici & Là - T-shirts et Souvenirs des régions - Acheter québécois | `ici-la.co` | shopify | 20 075 | 2026-08-23 15:14 |
28 +| GAGNON - La Grande Quincaillerie | `gagnonlgq.com` | shopify | 19 519 | 2026-08-23 15:10 |
29 +| Pieces de remorques et accessoires - Acheter québécois | `remorquetrailer.com` | woocommerce | 19 372 | 2026-08-23 13:43 |
30 +| EPIPRESTO | `epipresto.ca` | shopify | 13 266 | 2026-08-23 13:59 |
31 +| La Boite à Grains | `laboiteagrains.com` | shopify | 10 403 | 2026-08-23 14:00 |
32 +| La Maison du Bleuet | `lamaisondubleuet.com` | shopify | 8 652 | 2026-08-23 15:16 |
33 +| Bijouterie Jodoin | `bijouteriejodoin.com` | shopify | 8 012 | 2026-08-23 14:53 |
34 +| Oberson | `oberson.com` | shopify | 7 519 | 2026-08-23 13:34 |
35 +| Coopérative La Manne - Goûtez-y! | `cooplamanne.com` | woocommerce | 7 220 | 2026-08-23 15:03 |
36 +| LilloJEUX | `lillojeux.ca` | woocommerce | 6 608 | 2026-08-23 15:22 |
37 +| Paperole | `paperole.com` | shopify | 4 970 | 2026-08-23 13:35 |
38 +| Veille sur toi Inc. - CMAQ | `veillesurtoi.com` | shopify | 4 455 | 2026-08-23 13:45 |
39 +| Chic Placard | `chicplacard.ca` | shopify | 4 419 | 2026-08-23 14:58 |
40 +| Norseco S.E.C. | `norseco.com` | woocommerce | 4 295 | 2026-08-23 13:57 |
41 +| Bijoux Medusa | `bijouxmedusa.com` | shopify | 3 797 | 2026-08-23 14:53 |
41 42
42 43 ## Gotchas transverses
43 44
modified docs/connecteurs/decouverte-registre.md +20 −19
@@ -1,16 +1,16 @@
1 1 # Découverte & registre (`data/stores.json`)
2 2
3 −*Généré le 2026-08-19 03:40 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
3 +*Généré le 2026-08-23 15:39 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
4 4
5 −Registre généré le **2026-08-18** — **3507 boutiques** (champ `count`), toutes avec id (domaine canonique), plateforme, endpoint catalogue, classe d'origine, preuves et sources de découverte.
5 +Registre généré le **2026-08-21** — **4082 boutiques** (champ `count`), toutes avec id (domaine canonique), plateforme, endpoint catalogue, classe d'origine, preuves et sources de découverte.
6 6
7 7 ## Classes d'origine (`origin_class`)
8 8
9 9 | Classe | Boutiques | Signification |
10 10 |---|---|---|
11 −| A | 3303 | fabrication/production au Québec attestée |
12 −| C | 37 | marque québécoise (fabrication partielle ou incertaine) |
13 −| E | 167 | à requalifier / preuve faible |
11 +| A | 3864 | fabrication/production au Québec attestée |
12 +| C | 39 | marque québécoise (fabrication partielle ou incertaine) |
13 +| E | 179 | à requalifier / preuve faible |
14 14
15 15 Confiance : `origin_confidence` (0-1) + `origin_evidence` (texte de preuve, annuaire ou mention sur le site).
16 16
@@ -19,6 +19,7 @@ Confiance : `origin_confidence` (0-1) + `origin_evidence` (texte de preuve, annu
19 19 | Source | Boutiques |
20 20 |---|---|
21 21 | `alimentsduquebec_ent` | 752 |
22 +| `cartv_bio` | 340 |
22 23 | `lesproduitsduquebec_ent` | 329 |
23 24 | `charlevoix` | 304 |
24 25 | `zoneboreale` | 264 |
@@ -32,28 +33,28 @@ Confiance : `origin_confidence` (0-1) + `origin_evidence` (texte de preuve, annu
32 33 | `search_sweep_nonfood` | 104 |
33 34 | `search_sweep_vendors` | 97 |
34 35 | `search_sweep_cmaq` | 94 |
35 −| `marchespublics` | 80 |
36 36
37 −Statuts de vérification : `verified` : 2273, `probable` : 1234
37 +Statuts de vérification : `verified` : 2656, `probable` : 1426
38 38
39 39 ## Plateformes détectées au registre
40 40
41 41 | Plateforme | Boutiques |
42 42 |---|---|
43 −| `(vide)` | 873 |
44 −| `woocommerce` | 756 |
45 −| `shopify` | 702 |
46 −| `wordpress` | 564 |
47 −| `wix` | 339 |
48 −| `squarespace` | 128 |
49 −| `square` | 56 |
43 +| `(vide)` | 1000 |
44 +| `woocommerce` | 888 |
45 +| `shopify` | 763 |
46 +| `wordpress` | 668 |
47 +| `wix` | 393 |
48 +| `squarespace` | 157 |
49 +| `square` | 68 |
50 +| `votresite` | 45 |
51 +| `lightspeed` | 23 |
50 52 | `generic` | 22 |
51 −| `lightspeed` | 20 |
52 −| `ecwid` | 15 |
53 −| `snipcart` | 14 |
54 −| `magento` | 9 |
53 +| `ecwid` | 19 |
54 +| `snipcart` | 15 |
55 +| `magento` | 11 |
55 56 | `prestashop` | 8 |
56 −| `bigcommerce` | 1 |
57 +| `bigcommerce` | 2 |
57 58
58 59 ## Re-sondage (`scripts/reprobe_stores.py`)
59 60
modified docs/connecteurs/ecwid.md +6 −2
@@ -1,6 +1,6 @@
1 1 # Ecwid — verdict : NON COUVERT
2 2
3 −*Généré le 2026-08-19 03:40 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
3 +*Généré le 2026-08-23 15:39 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
4 4
5 5 ## Verdict
6 6
@@ -14,15 +14,19 @@
14 14 - Conséquence : les boutiques Ecwid restent au registre (`enabled=0`,
15 15 plateforme détectée) en attente d'une éventuelle voie d'accès.
16 16
17 −## Boutiques Ecwid recensées (15)
17 +## Boutiques Ecwid recensées (19)
18 18
19 19 | Boutique | Domaine | Statut registre |
20 20 |---|---|---|
21 21 | Spiritueux Alpha Tango | `alphatango.ca` | désactivée (pas d'endpoint) |
22 22 | Boswell Brasserie Artisanale | `brasserieboswell.com` | désactivée (pas d'endpoint) |
23 23 | Camp de Base Brasserie Artisanale | `brasseriecampdebase.com` | désactivée (pas d'endpoint) |
24 +| Fruits et Légumes en gros Montréal | `canadawidefruits.com` | désactivée (pas d'endpoint) |
25 +| Ferme Charejo inc. | `charejo.com` | désactivée (pas d'endpoint) |
24 26 | Crème Boulangerie Pâtisserie | `cremecreme.ca` | désactivée (pas d'endpoint) |
25 27 | Centre de production DAÏMÔN | `daimon.qc.ca` | désactivée (pas d'endpoint) |
28 +| Dums Coffee inc. | `dumscoffee.com` | désactivée (pas d'endpoint) |
29 +| Érablière Hatley | `erablierehatley.com` | désactivée (pas d'endpoint) |
26 30 | Ferme Gadbois | `fermegadbois.com` | désactivée (pas d'endpoint) |
27 31 | Frescadel International Inc. | `frescadel.com` | désactivée (pas d'endpoint) |
28 32 | Fromagerie de l'Île-aux-Grues (Agrilait s.e.c.) | `fromagesileauxgrues.com` | désactivée (pas d'endpoint) |
modified docs/connecteurs/enrichissement-boutiques.md +3 −3
@@ -1,16 +1,16 @@
1 1 # Enrichissement des boutiques
2 2
3 −*Généré le 2026-08-19 03:40 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
3 +*Généré le 2026-08-23 15:39 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
4 4
5 5 Deux scripts rejouables complètent la table `stores` (colonnes additives `logo_url`, `cover_url`, `description_meta`, `shipping_info`).
6 6
7 7 ## `scripts/enrich_stores.py` — logo / couverture / description
8 8
9 −- Couverture actuelle : **logo 3220/3507** (91.8 %), **cover 1938/3507** (55.3 %).
9 +- Couverture actuelle : **logo 3220/4082** (78.9 %), **cover 1938/4082** (47.5 %).
10 10 - Cache disque `data/enrich_cache/` : 3224 fichiers (page d'accueil analysée une seule fois ; Scrapfly en secours pour les 403).
11 11
12 12 ## `scripts/enrich_shipping.py` — politiques de livraison (vague 2)
13 13
14 −- Couverture actuelle : **shipping_info 365/3507** (10.4 %) — ciblé sur les boutiques productives (`product_count > 0`).
14 +- Couverture actuelle : **shipping_info 365/4082** (8.9 %) — ciblé sur les boutiques productives (`product_count > 0`).
15 15 - Cache disque `data/enrich_cache/shipping/` : 618 fichiers (échecs mémorisés pour ne pas re-marteler les sites).
16 16
modified docs/connecteurs/generic.md +8 −8
@@ -1,6 +1,6 @@
1 1 # Connecteur générique (JSON-LD / microdata / OG) (`generic`)
2 2
3 −*Généré le 2026-08-19 03:40 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
3 +*Généré le 2026-08-23 15:39 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
4 4
5 5 ## Mécanique / endpoint
6 6
@@ -21,24 +21,24 @@
21 21
22 22 ## Boutiques rattachées
23 23
24 −- Registre `data/stores.json` : **74** boutiques
24 +- Registre `data/stores.json` : **81** boutiques
25 25 - En base (table `stores`) : **30** activées, **23** avec produits
26 26
27 27 **Top 5 par volume :**
28 28
29 29 | Boutique | Domaine | Produits | Dernier sync | Statut |
30 30 |---|---|---|---|---|
31 −| Alpha Signa | `alphasigna.com` | 800 | 2026-08-19 01:10 | ok |
32 −| Bijouterie Concept | `bijouterieconcept.com` | 800 | 2026-08-19 01:52 | ok |
33 −| Mondou | `mondou.com` | 799 | 2026-08-19 03:05 | ok |
34 −| Boutique Nomade | `boutiquenomade.net` | 799 | 2026-08-19 01:30 | ok |
35 −| Bijouterie Pénélope | `bijouteriepenelope.com` | 798 | 2026-08-19 01:20 | ok |
31 +| Alpha Signa | `alphasigna.com` | 800 | 2026-08-23 14:49 | ok |
32 +| Bijouterie Concept | `bijouterieconcept.com` | 800 | 2026-08-23 15:31 | ok |
33 +| Mondou | `mondou.com` | 799 | 2026-08-23 15:31 | ok |
34 +| Boutique Nomade | `boutiquenomade.net` | 799 | 2026-08-23 14:55 | ok |
35 +| Bijouterie Pénélope | `bijouteriepenelope.com` | 798 | 2026-08-23 14:52 | ok |
36 36
37 37 ## Volumétrie & complétude (BD live)
38 38
39 39 | Indicateur | Valeur |
40 40 |---|---|
41 −| Produits actifs | 8 232 |
41 +| Produits actifs | 8 228 |
42 42 | Prix | 100.0 % |
43 43 | Photos | 82.8 % |
44 44 | Description | 95.4 % |
modified docs/connecteurs/scrapfly-transport.md +1 −1
@@ -1,6 +1,6 @@
1 1 # Transport de secours Scrapfly (`scrapfly-transport`)
2 2
3 −*Généré le 2026-08-19 03:40 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
3 +*Généré le 2026-08-23 15:39 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
4 4
5 5 ## Mécanique
6 6
modified docs/connecteurs/shopify.md +12 −12
@@ -1,6 +1,6 @@
1 1 # Connecteur Shopify (`shopify`)
2 2
3 −*Généré le 2026-08-19 03:40 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
3 +*Généré le 2026-08-23 15:39 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
4 4
5 5 ## Mécanique / endpoint
6 6
@@ -17,27 +17,27 @@
17 17
18 18 ## Boutiques rattachées
19 19
20 −- Registre `data/stores.json` : **702** boutiques
21 −- En base (table `stores`) : **662** activées, **642** avec produits
20 +- Registre `data/stores.json` : **763** boutiques
21 +- En base (table `stores`) : **715** activées, **694** avec produits
22 22
23 23 **Top 5 par volume :**
24 24
25 25 | Boutique | Domaine | Produits | Dernier sync | Statut |
26 26 |---|---|---|---|---|
27 −| Ici & Là - T-shirts et Souvenirs des régions - Acheter québécois | `ici-la.co` | 20 075 | 2026-08-19 02:27 | ok |
28 −| GAGNON - La Grande Quincaillerie | `gagnonlgq.com` | 19 516 | 2026-08-19 02:16 | ok |
29 −| La Maison du Bleuet | `lamaisondubleuet.com` | 8 629 | 2026-08-19 02:36 | ok |
30 −| Bijouterie Jodoin | `bijouteriejodoin.com` | 8 252 | 2026-08-19 01:24 | ok |
31 −| Oberson | `oberson.com` | 7 419 | 2026-08-19 03:14 | ok |
27 +| Ici & Là - T-shirts et Souvenirs des régions - Acheter québécois | `ici-la.co` | 20 075 | 2026-08-23 15:14 | ok |
28 +| GAGNON - La Grande Quincaillerie | `gagnonlgq.com` | 19 519 | 2026-08-23 15:10 | ok |
29 +| EPIPRESTO | `epipresto.ca` | 13 266 | 2026-08-23 13:59 | ok |
30 +| La Boite à Grains | `laboiteagrains.com` | 10 403 | 2026-08-23 14:00 | ok |
31 +| La Maison du Bleuet | `lamaisondubleuet.com` | 8 652 | 2026-08-23 15:16 | ok |
32 32
33 33 ## Volumétrie & complétude (BD live)
34 34
35 35 | Indicateur | Valeur |
36 36 |---|---|
37 −| Produits actifs | 207 187 |
38 −| Prix | 99.2 % |
39 −| Photos | 96.5 % |
40 −| Description | 94.0 % |
37 +| Produits actifs | 244 732 |
38 +| Prix | 99.3 % |
39 +| Photos | 96.8 % |
40 +| Description | 90.2 % |
41 41 | Détails (variantes/attributs) | 100.0 % |
42 42 | — dont avis (rating/review_count) | 0.0 % |
43 43 | — dont poids/dimensions | 0.1 % |
modified docs/connecteurs/square.md +9 −9
@@ -1,6 +1,6 @@
1 1 # Connecteur Square Online (`square`)
2 2
3 −*Généré le 2026-08-19 03:40 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
3 +*Généré le 2026-08-23 15:39 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
4 4
5 5 ## Mécanique / endpoint
6 6
@@ -21,27 +21,27 @@
21 21
22 22 ## Boutiques rattachées
23 23
24 −- Registre `data/stores.json` : **56** boutiques
24 +- Registre `data/stores.json` : **68** boutiques
25 25 - En base (table `stores`) : **36** activées, **36** avec produits
26 26
27 27 **Top 5 par volume :**
28 28
29 29 | Boutique | Domaine | Produits | Dernier sync | Statut |
30 30 |---|---|---|---|---|
31 −| BIZZ coopérative d’alimentation locale | `bizzcoop.com` | 558 | 2026-08-19 01:24 | ok |
32 −| À Outrance | `aoutrance.com` | 303 | 2026-08-19 01:08 | ok |
33 −| Misskikooz | `melissacharette.com` | 280 | 2026-08-19 02:59 | ok |
34 −| ÉCONOMUSÉE® du cidrier | `charlevoixenligne.com` | 213 | 2026-08-19 01:38 | ok |
35 −| Chaga aromatisé - Acheter québécois | `sorcieredepouvoir.com` | 213 | 2026-08-19 03:26 | ok |
31 +| BIZZ coopérative d’alimentation locale | `bizzcoop.com` | 558 | 2026-08-23 14:53 | ok |
32 +| À Outrance | `aoutrance.com` | 303 | 2026-08-23 14:49 | ok |
33 +| Misskikooz | `melissacharette.com` | 280 | 2026-08-23 15:27 | ok |
34 +| ÉCONOMUSÉE® du cidrier | `charlevoixenligne.com` | 213 | 2026-08-23 14:57 | ok |
35 +| Chaga aromatisé - Acheter québécois | `sorcieredepouvoir.com` | 213 | 2026-08-23 13:40 | ok |
36 36
37 37 ## Volumétrie & complétude (BD live)
38 38
39 39 | Indicateur | Valeur |
40 40 |---|---|
41 −| Produits actifs | 2 833 |
41 +| Produits actifs | 2 832 |
42 42 | Prix | 99.7 % |
43 43 | Photos | 92.5 % |
44 −| Description | 88.6 % |
44 +| Description | 88.5 % |
45 45 | Détails (variantes/attributs) | 100.0 % |
46 46 | — dont avis (rating/review_count) | 3.6 % |
47 47 | — dont poids/dimensions | 0.0 % |
modified docs/connecteurs/squarespace.md +9 −9
@@ -1,6 +1,6 @@
1 1 # Connecteur Squarespace (`squarespace`)
2 2
3 −*Généré le 2026-08-19 03:40 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
3 +*Généré le 2026-08-23 15:39 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
4 4
5 5 ## Mécanique / endpoint
6 6
@@ -17,27 +17,27 @@
17 17
18 18 ## Boutiques rattachées
19 19
20 −- Registre `data/stores.json` : **128** boutiques
20 +- Registre `data/stores.json` : **157** boutiques
21 21 - En base (table `stores`) : **27** activées, **23** avec produits
22 22
23 23 **Top 5 par volume :**
24 24
25 25 | Boutique | Domaine | Produits | Dernier sync | Statut |
26 26 |---|---|---|---|---|
27 −| Apéro à zéro | `aperoazero.ca` | 238 | 2026-08-19 01:09 | ok |
28 −| Les Mains d'ici | `lesmainsdici.com` | 106 | 2026-08-19 02:42 | ok |
29 −| Nos Cabanes S.E.N.C | `noscabanes.com` | 78 | 2026-08-19 03:12 | ok |
30 −| Hugo & Clay | `hugoandclay.com` | 42 | 2026-08-19 02:21 | ok |
31 −| Distillerie COMONT | `comont.ca` | 39 | 2026-08-19 01:43 | ok |
27 +| Apéro à zéro | `aperoazero.ca` | 235 | 2026-08-23 14:49 | ok |
28 +| Les Mains d'ici | `lesmainsdici.com` | 106 | 2026-08-23 15:17 | ok |
29 +| Nos Cabanes S.E.N.C | `noscabanes.com` | 78 | 2026-08-23 15:38 | ok |
30 +| Hugo & Clay | `hugoandclay.com` | 42 | 2026-08-23 15:09 | ok |
31 +| Atelier V Cuir | `ateliervcuir.com` | 39 | 2026-08-23 14:50 | ok |
32 32
33 33 ## Volumétrie & complétude (BD live)
34 34
35 35 | Indicateur | Valeur |
36 36 |---|---|
37 −| Produits actifs | 803 |
37 +| Produits actifs | 788 |
38 38 | Prix | 100.0 % |
39 39 | Photos | 99.6 % |
40 −| Description | 96.3 % |
40 +| Description | 96.2 % |
41 41 | Détails (variantes/attributs) | 0.0 % |
42 42 | — dont avis (rating/review_count) | 0.0 % |
43 43 | — dont poids/dimensions | 0.0 % |
added docs/connecteurs/votresite.md +65 −0
@@ -0,0 +1,65 @@
1 +# Connecteur Votresite.ca (Drupal + OpenCart) (`votresite`)
2 +
3 +*Généré le 2026-08-23 15:39 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
4 +
5 +## Mécanique / endpoint
6 +
7 +- Boutique OpenCart montée sous `/boutique` (parfois `/produits`, `/shop`) : inventaire par `<mount>/sitemap.xml` sinon crawl des catégories `<mount>/fr` (`?limit=100&page=N`), puis fiche par fiche `…/<slug>-p<ID>/` (rendu 100 % serveur, aucune API JSON).
8 +- Module : `fabrika/connectors/votresite.py`
9 +- Plateformes BD routées ici : `votresite`
10 +
11 +**En-tête du module :**
12 +
13 +> Fabri-Ka — Agrégateur de produits québécois
14 +> Auteur : Simon-Pierre Boucher — contact@spboucher.ai
15 +> connectors/votresite.py : connecteur Votresite.ca (plateforme québécoise).
16 +> Les sites Votresite.ca sont des Drupal 8 gérés (thème owebo-votresite) avec
17 +> une boutique OpenCart montée dans un sous-répertoire (/boutique/ ou
18 +> /produits/, parfois autre). Rendu 100 % serveur, aucune API JSON :
19 +> - inventaire : <mount>/sitemap.xml (extension OpenCart, pas toujours
20 +> activée) sinon crawl des catégories <mount>/fr + pagination
21 +> ?limit=100&page=N ;
22 +> - fiche : URL …/<slug>-p<ID>[c<ID>…]/ — prix courant dans <h2>…$</h2>,
23 +> prix barré (spécial) dans <span style="text-decoration: line-through">,
24 +> « Disponibilité: » / « Modèle: » en <li>, description div#tab-description,
25 +> galerie <a class="thumbnail">. Les meta twitter:data1/2 servent de
26 +> secours mais affichent le prix RÉGULIER même en solde.
27 +> Dédup par ID produit (le même p<ID> apparaît sous plusieurs chemins de
28 +> catégorie, ex. -p361c37c45c44).
29 +
30 +## Boutiques rattachées
31 +
32 +- Registre `data/stores.json` : **45** boutiques
33 +- En base (table `stores`) : **45** activées, **43** avec produits
34 +
35 +**Top 5 par volume :**
36 +
37 +| Boutique | Domaine | Produits | Dernier sync | Statut |
38 +|---|---|---|---|---|
39 +| Bijouterie Simard | `bijouteriesimard.ca` | 488 | 2026-08-23 15:36 | ok |
40 +| Zylvery-Bijoux Design | `zylverybijouxdesign.com` | 312 | 2026-08-23 15:36 | ok |
41 +| AlpagAdore | `alpagadore.com` | 234 | 2026-08-23 15:35 | ok |
42 +| Bourdeau artiste peintre | `bourdeauartistepeintre.com` | 182 | 2026-08-23 15:35 | ok |
43 +| Les Moniales de Bethléem - CMAQ | `monasteredebethleem.ca` | 174 | 2026-08-23 15:36 | ok |
44 +
45 +## Volumétrie & complétude (BD live)
46 +
47 +| Indicateur | Valeur |
48 +|---|---|
49 +| Produits actifs | 3 190 |
50 +| Prix | 95.5 % |
51 +| Photos | 100.0 % |
52 +| Description | 100.0 % |
53 +| Détails (variantes/attributs) | 100.0 % |
54 +| — dont avis (rating/review_count) | 0.0 % |
55 +| — dont poids/dimensions | 0.0 % |
56 +
57 +## Gotchas
58 +
59 +- **Plateforme québécoise** (scripts.votresite.ca) : vitrine Drupal 8 géré (thème `owebo-votresite`) + boutique OpenCart en sous-répertoire — le montage est détecté via le registre, la page d'accueil, puis `/boutique`/`/produits`.
60 +- **Prix : le HTML d'abord, les meta en secours** — en solde, `twitter:data1` affiche le prix RÉGULIER ; le prix courant est le `<h2>…$</h2>` de la fiche et le prix barré le `<span>` `text-decoration: line-through` (→ `compare_at_price`).
61 +- **Titre = dernier `<h1>` sans ancre** : le premier `<h1>` est le logo du site (un lien) sur plusieurs thèmes ; `og:title` peut être du bourrage de mots-clés (ex. lemieldabee.ca).
62 +- **Dédup par ID produit** : le même `p<ID>` apparaît sous plusieurs chemins de catégorie (`-p361c37c45c44`).
63 +- Les URLs d'images OpenCart contiennent espaces/accents bruts (`image/cache/catalog/…`) — encodées avant stockage.
64 +
65 +Voir aussi : [INDEX](INDEX.md) · [transport Scrapfly](scrapfly-transport.md) · [découverte & registre](decouverte-registre.md).
modified docs/connecteurs/wix.md +14 −14
@@ -1,6 +1,6 @@
1 1 # Connecteur Wix Stores (`wix`)
2 2
3 −*Généré le 2026-08-19 03:40 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
3 +*Généré le 2026-08-23 15:39 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
4 4
5 5 ## Mécanique / endpoint
6 6
@@ -18,30 +18,30 @@
18 18
19 19 ## Boutiques rattachées
20 20
21 −- Registre `data/stores.json` : **339** boutiques
22 −- En base (table `stores`) : **339** activées, **197** avec produits
21 +- Registre `data/stores.json` : **393** boutiques
22 +- En base (table `stores`) : **302** activées, **240** avec produits
23 23
24 24 **Top 5 par volume :**
25 25
26 26 | Boutique | Domaine | Produits | Dernier sync | Statut |
27 27 |---|---|---|---|---|
28 −| Bijouterie Alarie | `bijouteriealarie.com` | 909 | 2026-08-19 01:19 | ok |
29 −| Savonnerie Histoire de Bulles | `histoiredebulles.com` | 514 | 2026-08-19 02:21 | ok |
30 −| Petits Fruits St-Louis | `souslesoliviers.ca` | 281 | 2026-08-18 22:09 | ok |
31 −| CRÉATIONS GLi - CMAQ | `bijouxgli.com` | 202 | 2026-08-19 01:21 | ok |
32 −| Savonnerie Bon Bain | `savonneriebonbain.ca` | 180 | 2026-08-19 03:17 | ok |
28 +| Bijouterie Alarie | `bijouteriealarie.com` | 907 | 2026-08-23 14:51 | ok |
29 +| Savonnerie Histoire de Bulles | `histoiredebulles.com` | 514 | 2026-08-23 15:09 | ok |
30 +| Bidon Rempli inc. | `aubidonrempli.com` | 315 | 2026-08-23 13:52 | ok |
31 +| Petits Fruits St-Louis | `souslesoliviers.ca` | 281 | 2026-08-23 13:51 | ok |
32 +| Ferme Les Carottés inc. | `fermelescarottes.com` | 230 | 2026-08-23 13:55 | ok |
33 33
34 34 ## Volumétrie & complétude (BD live)
35 35
36 36 | Indicateur | Valeur |
37 37 |---|---|
38 −| Produits actifs | 7 423 |
39 −| Prix | 97.0 % |
40 −| Photos | 98.6 % |
41 −| Description | 90.1 % |
42 −| Détails (variantes/attributs) | 97.9 % |
38 +| Produits actifs | 8 924 |
39 +| Prix | 97.1 % |
40 +| Photos | 98.5 % |
41 +| Description | 90.4 % |
42 +| Détails (variantes/attributs) | 97.5 % |
43 43 | — dont avis (rating/review_count) | 0.0 % |
44 −| — dont poids/dimensions | 12.4 % |
44 +| — dont poids/dimensions | 11.1 % |
45 45
46 46 ## Gotchas
47 47
modified docs/connecteurs/woocommerce.md +15 −15
@@ -1,6 +1,6 @@
1 1 # Connecteur WooCommerce (Store API) (`woocommerce`)
2 2
3 −*Généré le 2026-08-19 03:40 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
3 +*Généré le 2026-08-23 15:39 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.*
4 4
5 5 ## Mécanique / endpoint
6 6
@@ -17,30 +17,30 @@
17 17
18 18 ## Boutiques rattachées
19 19
20 −- Registre `data/stores.json` : **1320** boutiques
21 −- En base (table `stores`) : **476** activées, **442** avec produits
20 +- Registre `data/stores.json` : **1556** boutiques
21 +- En base (table `stores`) : **546** activées, **509** avec produits
22 22
23 23 **Top 5 par volume :**
24 24
25 25 | Boutique | Domaine | Produits | Dernier sync | Statut |
26 26 |---|---|---|---|---|
27 −| Pieces de remorques et accessoires - Acheter québécois | `remorquetrailer.com` | 19 358 | 2026-08-19 03:23 | ok |
28 −| Coopérative La Manne - Goûtez-y! | `cooplamanne.com` | 7 216 | 2026-08-19 01:48 | ok |
29 −| LilloJEUX | `lillojeux.ca` | 6 590 | 2026-08-19 02:50 | ok |
30 −| Létourno | `letourno.com` | 2 552 | 2026-08-19 02:49 | ok |
31 −| Fourrures Grenier | `grenierboutique.ca` | 2 345 | 2026-08-19 02:19 | ok |
27 +| Pieces de remorques et accessoires - Acheter québécois | `remorquetrailer.com` | 19 372 | 2026-08-23 13:43 | ok |
28 +| Coopérative La Manne - Goûtez-y! | `cooplamanne.com` | 7 220 | 2026-08-23 15:03 | ok |
29 +| LilloJEUX | `lillojeux.ca` | 6 608 | 2026-08-23 15:22 | ok |
30 +| Norseco S.E.C. | `norseco.com` | 4 295 | 2026-08-23 13:57 | ok |
31 +| Aliments Merci | `alimentsmerci.com` | 2 829 | 2026-08-23 13:53 | ok |
32 32
33 33 ## Volumétrie & complétude (BD live)
34 34
35 35 | Indicateur | Valeur |
36 36 |---|---|
37 −| Produits actifs | 74 048 |
38 −| Prix | 94.0 % |
39 −| Photos | 71.8 % |
40 −| Description | 63.6 % |
41 −| Détails (variantes/attributs) | 86.6 % |
42 −| — dont avis (rating/review_count) | 3.8 % |
43 −| — dont poids/dimensions | 37.5 % |
37 +| Produits actifs | 92 521 |
38 +| Prix | 86.4 % |
39 +| Photos | 71.5 % |
40 +| Description | 66.6 % |
41 +| Détails (variantes/attributs) | 87.8 % |
42 +| — dont avis (rating/review_count) | 3.2 % |
43 +| — dont poids/dimensions | 31.5 % |
44 44
45 45 ## Gotchas
46 46
modified fabrika/connectors/__init__.py +2 −0
@@ -10,6 +10,7 @@ from .generic import GenericConnector
10 10 from .shopify import ShopifyConnector
11 11 from .square import SquareConnector
12 12 from .squarespace import SquarespaceConnector
13 +from .votresite import VotresiteConnector
13 14 from .wix import WixConnector
14 15 from .woocommerce import WooCommerceConnector
15 16
@@ -20,6 +21,7 @@ PLATFORM_CONNECTORS: dict[str, type[BaseConnector]] = {
20 21 "squarespace": SquarespaceConnector,
21 22 "square": SquareConnector,
22 23 "wix": WixConnector,
24 + "votresite": VotresiteConnector, # Votresite.ca (QC) : Drupal + OpenCart
23 25 # plateformes à rendu serveur → extraction du balisage produit (JSON-LD…)
24 26 "prestashop": GenericConnector,
25 27 "magento": GenericConnector,
added fabrika/connectors/votresite.py +302 −0
@@ -0,0 +1,302 @@
1 +# -----------------------------------------------------------------------------
2 +# Fabri-Ka — Agrégateur de produits québécois
3 +# Auteur : Simon-Pierre Boucher — contact@spboucher.ai
4 +# connectors/votresite.py : connecteur Votresite.ca (plateforme québécoise).
5 +# Les sites Votresite.ca sont des Drupal 8 gérés (thème owebo-votresite) avec
6 +# une boutique OpenCart montée dans un sous-répertoire (/boutique/ ou
7 +# /produits/, parfois autre). Rendu 100 % serveur, aucune API JSON :
8 +# - inventaire : <mount>/sitemap.xml (extension OpenCart, pas toujours
9 +# activée) sinon crawl des catégories <mount>/fr + pagination
10 +# ?limit=100&page=N ;
11 +# - fiche : URL …/<slug>-p<ID>[c<ID>…]/ — prix courant dans <h2>…$</h2>,
12 +# prix barré (spécial) dans <span style="text-decoration: line-through">,
13 +# « Disponibilité: » / « Modèle: » en <li>, description div#tab-description,
14 +# galerie <a class="thumbnail">. Les meta twitter:data1/2 servent de
15 +# secours mais affichent le prix RÉGULIER même en solde.
16 +# Dédup par ID produit (le même p<ID> apparaît sous plusieurs chemins de
17 +# catégorie, ex. -p361c37c45c44).
18 +# -----------------------------------------------------------------------------
19 +from __future__ import annotations
20 +
21 +import concurrent.futures as cf
22 +import re
23 +from html import unescape
24 +
25 +from ..schema import Product, parse_price
26 +from .base import BaseConnector
27 +
28 +# …/slug-p361/ ou …/slug-p361c37c45/ (produit) ; …/slug-c116c139/ (catégorie)
29 +PROD_URL_RE = re.compile(r"/([^/]+)-p(\d+)(?:c\d+)*/?(?:\?.*)?$")
30 +CAT_URL_RE = re.compile(r"-c\d+(?:c\d+)*/?$")
31 +LOC_RE = re.compile(r"<loc>\s*(?:<!\[CDATA\[)?\s*(.*?)\s*(?:\]\]>)?\s*</loc>",
32 + re.I | re.S)
33 +HREF_RE = re.compile(r'href="([^"]+)"')
34 +SKIP_RE = re.compile(r"(/account|/cart|/checkout|/wishlist|/compare|/login|"
35 + r"/register|route=|mailto:|tel:|javascript:)", re.I)
36 +
37 +# marqueurs OpenCart d'une boutique Votresite valide
38 +_OC_MARKERS = ("image/cache", "route=product", 'class="thumbnails"',
39 + "list-unstyled")
40 +
41 +CANDIDATE_MOUNTS = ["/boutique", "/produits"]
42 +
43 +
44 +def _clean(s: str | None) -> str:
45 + return unescape(re.sub(r"\s+", " ", re.sub(r"<[^>]+>", " ", s or ""))).strip()
46 +
47 +
48 +def _enc(url: str) -> str:
49 + """Les chemins d'images OpenCart contiennent espaces et accents bruts."""
50 + return url.replace(" ", "%20")
51 +
52 +
53 +class VotresiteConnector(BaseConnector):
54 + platform = "votresite"
55 + request_delay = 0.2
56 + max_products = 2000
57 + max_listing_pages = 250 # garde-fou du crawl catégories
58 +
59 + # ------------------------------------------------------------------ mount
60 + def _try_mount(self, mount: str) -> bool:
61 + try:
62 + r = self.get(f"{self.base}{mount}/fr")
63 + except Exception:
64 + return False
65 + html = r.text or ""
66 + return (r.status_code == 200
67 + and any(m in html for m in _OC_MARKERS)
68 + and (PROD_URL_RE.search(html) is not None
69 + or re.search(r'-[pc]\d+[c\d]*/"', html) is not None
70 + or "-c" in html))
71 +
72 + def _discover_mount(self) -> str:
73 + ep = (self.store.get("catalog_endpoint") or "").strip().rstrip("/")
74 + candidates: list[str] = []
75 + if ep and ep != "__generic__":
76 + candidates.append(ep if ep.startswith("/") else f"/{ep}")
77 + # page d'accueil Drupal : le lien vers la boutique révèle le montage
78 + try:
79 + html = self.get(self.base + "/").text
80 + for m in re.finditer(
81 + r'href="https?://[^"/]+(/[a-z0-9_-]+)(?:/fr)?/?"', html, re.I):
82 + p = m.group(1)
83 + if re.search(r"boutique|produit|magasin|commander|achat", p, re.I):
84 + candidates.append(p)
85 + for m in re.finditer(
86 + r'href="https?://[^"/]+(/[a-z0-9_-]+)/fr/[^"]*-[pc]\d', html):
87 + candidates.append(m.group(1))
88 + except Exception:
89 + pass
90 + candidates += CANDIDATE_MOUNTS
91 + seen: set[str] = set()
92 + for c in candidates:
93 + c = c.rstrip("/")
94 + if not c or c in seen:
95 + continue
96 + seen.add(c)
97 + if self._try_mount(c):
98 + return c
99 + raise RuntimeError("boutique Votresite (OpenCart) introuvable "
100 + f"(montages essayés : {sorted(seen)})")
101 +
102 + # -------------------------------------------------------------- inventaire
103 + def _sitemap_urls(self, mount: str) -> dict[str, str]:
104 + """{pid: url produit} depuis <mount>/sitemap.xml (souvent absent)."""
105 + out: dict[str, str] = {}
106 + try:
107 + r = self.get(f"{self.base}{mount}/sitemap.xml")
108 + except Exception:
109 + return out
110 + xml = r.text or ""
111 + if r.status_code != 200 or "<urlset" not in xml:
112 + return out
113 + for loc in LOC_RE.findall(xml):
114 + m = PROD_URL_RE.search(loc)
115 + if m:
116 + out.setdefault(m.group(2), loc)
117 + return out
118 +
119 + def _crawl_urls(self, mount: str) -> dict[str, str]:
120 + """Crawl des pages catégories : {pid: url produit}."""
121 + root = f"{self.base}{mount}"
122 + prods: dict[str, str] = {}
123 + seen: set[str] = set()
124 + queue: list[str] = [f"{root}/fr"]
125 + fetched = 0
126 + while queue and fetched < self.max_listing_pages:
127 + url = queue.pop(0)
128 + key = url.rstrip("/")
129 + if key in seen:
130 + continue
131 + seen.add(key)
132 + try:
133 + html = self.get(url).text or ""
134 + except Exception:
135 + continue
136 + fetched += 1
137 + for href in HREF_RE.findall(html):
138 + href = unescape(href).split("#")[0]
139 + if not href.startswith(root) or SKIP_RE.search(href):
140 + continue
141 + pm = PROD_URL_RE.search(href.split("?")[0])
142 + if pm:
143 + prods.setdefault(pm.group(2), href.split("?")[0])
144 + continue
145 + path = href.split("?")[0]
146 + if CAT_URL_RE.search(path):
147 + # 100 produits par page de liste (défaut : 15)
148 + if path.rstrip("/") + "/?limit=100" not in seen:
149 + queue.append(path.rstrip("/") + "/?limit=100")
150 + elif "page=" in href and "limit=" in href:
151 + queue.append(href) # pagination déjà paramétrée
152 + if len(prods) >= self.max_products:
153 + break
154 + return prods
155 +
156 + # ------------------------------------------------------------------ fiche
157 + def _parse_product(self, pid: str, url: str, html: str) -> Product | None:
158 + # le 1er <h1> est souvent le logo du site (un lien) ; le titre du
159 + # produit est le dernier <h1> SANS ancre (ex. lemieldabee.ca)
160 + title, h1_pos = None, -1
161 + h1s = list(re.finditer(r"<h1[^>]*>(.*?)</h1>", html, re.S))
162 + plain = [m for m in h1s if "<a " not in m.group(1)]
163 + chosen = (plain or h1s)[-1] if h1s else None
164 + if chosen and plain:
165 + title, h1_pos = _clean(chosen.group(1)), chosen.start()
166 + if not title:
167 + m = re.search(r'<meta[^>]+property="og:title"[^>]+content="([^"]+)"',
168 + html)
169 + title = _clean(m.group(1)) if m else None
170 + if chosen:
171 + h1_pos = chosen.start()
172 + if not title:
173 + return None
174 +
175 + # zone d'info produit : entre le <h1> et le formulaire d'achat
176 + if h1_pos < 0:
177 + h1_pos = 0
178 + zone_end = html.find('<div id="product"', h1_pos)
179 + zone = html[h1_pos: zone_end if zone_end > h1_pos else h1_pos + 6000]
180 +
181 + compare = None
182 + m = re.search(r"line-through[^>]*>\s*([^<]*\d[^<]*)</", zone)
183 + if m:
184 + compare = parse_price(m.group(1))
185 + price = None
186 + m = re.search(r"<h2[^>]*>\s*([^<]*\d[^<]*\$[^<]*)</h2>", zone)
187 + if m:
188 + price = parse_price(m.group(1))
189 + if price is None: # secours : meta twitter (prix régulier)
190 + m = re.search(r'twitter:data1"\s+content="([^"]+)"', html)
191 + if m:
192 + price = parse_price(m.group(1))
193 + if compare is not None and price is not None and compare <= price:
194 + compare = None
195 +
196 + available = None
197 + m = (re.search(r"Disponibilité\s*:\s*</?[^>]*>?\s*([^<]+)<", zone)
198 + or re.search(r'twitter:data2"\s+content="([^"]+)"', html))
199 + dispo = _clean(m.group(1)) if m else ""
200 + if dispo:
201 + low = dispo.lower()
202 + if "rupture" in low or "épuis" in low or "epuis" in low:
203 + available = False
204 + elif "stock" in low or "commande" in low or "jour" in low:
205 + available = True
206 +
207 + det: dict = {}
208 + m = re.search(r"Modèle\s*:\s*([^<]+)<", zone)
209 + if m and _clean(m.group(1)):
210 + det["model"] = _clean(m.group(1))
211 + if dispo:
212 + det["availability_text"] = dispo
213 +
214 + # options (listes déroulantes OpenCart)
215 + opts = []
216 + for sel in re.finditer(
217 + r'<label[^>]*control-label[^>]*>(.*?)</label>\s*<select[^>]*'
218 + r'name="option\[\d+\]"[^>]*>(.*?)</select>', html, re.S):
219 + name = _clean(sel.group(1))
220 + values = [_clean(v) for v in
221 + re.findall(r"<option[^>]*>(.*?)</option>", sel.group(2), re.S)]
222 + values = [v for v in values if v and "choisir" not in v.lower()]
223 + if name and values:
224 + opts.append({"name": name, "values": values[:30]})
225 + if opts:
226 + det["options"] = opts
227 +
228 + # description : div#tab-description jusqu'au prochain onglet/bloc
229 + desc = ""
230 + start = html.find('id="tab-description"')
231 + if start != -1:
232 + start = html.find(">", start) + 1
233 + cuts = [html.find(marker, start) for marker in
234 + ('id="tab-', 'class="related', "<footer", "Produits apparentés")]
235 + cuts = [c for c in cuts if c > start]
236 + desc = html[start: min(cuts) if cuts else start + 20000]
237 + if not _clean(desc):
238 + m = (re.search(r'<meta[^>]+property="og:description"[^>]+content="([^"]+)"', html)
239 + or re.search(r'<meta[^>]+name="description"[^>]+content="([^"]+)"', html))
240 + desc = m.group(1) if m else ""
241 +
242 + images: list[str] = []
243 + for m in re.finditer(r'<a[^>]+class="thumbnail"[^>]+href="([^"]+)"', html):
244 + u = _enc(unescape(m.group(1)))
245 + if u.startswith("http") and u not in images:
246 + images.append(u)
247 + m = re.search(r'<meta[^>]+property="og:image"[^>]+content="([^"]+)"', html)
248 + if m:
249 + u = _enc(unescape(m.group(1)))
250 + if u.startswith("http") and u not in images:
251 + images.append(u)
252 +
253 + # catégories du fil d'Ariane (sans l'accueil ni le produit lui-même)
254 + cats: list[str] = []
255 + m = re.search(r'<ul class="breadcrumb"[^>]*>(.*?)</ul>', html, re.S)
256 + if m:
257 + entries = re.findall(r"<a[^>]*>(.*?)</a>", m.group(1), re.S)
258 + cats = [_clean(e) for e in entries
259 + if _clean(e) and "fa-home" not in e and _clean(e) != title]
260 +
261 + return Product(
262 + store_id=self.store_id,
263 + external_id=pid,
264 + url=url,
265 + title=title,
266 + description=desc,
267 + price=price,
268 + price_max=price,
269 + compare_at_price=compare,
270 + images=images,
271 + product_type=cats[-1] if cats else "",
272 + tags=cats,
273 + available=available,
274 + details=det,
275 + )
276 +
277 + # ------------------------------------------------------------------ fetch
278 + def fetch(self) -> list[Product]:
279 + mount = self._discover_mount()
280 + urls = self._sitemap_urls(mount)
281 + if len(urls) < 3: # sitemap absent ou quasi vide -> crawl
282 + crawled = self._crawl_urls(mount)
283 + for pid, u in crawled.items():
284 + urls.setdefault(pid, u)
285 + items = list(urls.items())[: self.max_products]
286 + out: list[Product] = []
287 +
288 + def work(item: tuple[str, str]) -> Product | None:
289 + pid, u = item
290 + try:
291 + html = self.get(u).text or ""
292 + except Exception:
293 + return None
294 + if len(html) < 500:
295 + return None
296 + return self._parse_product(pid, u, html)
297 +
298 + with cf.ThreadPoolExecutor(6) as ex:
299 + for rec in ex.map(work, items):
300 + if rec:
301 + out.append(rec)
302 + return out
modified scripts/gen_connector_docs.py +24 −0
@@ -45,6 +45,7 @@ GROUPS: dict[str, list[str]] = {
45 45 "wix": ["wix"],
46 46 "squarespace": ["squarespace"],
47 47 "square": ["square"],
48 + "votresite": ["votresite"],
48 49 "generic": ["generic", "prestashop", "magento", "bigcommerce",
49 50 "lightspeed", "snipcart"],
50 51 }
@@ -102,6 +103,29 @@ FICHES = {
102 103 "connectables les boutiques Square jusque-là à 0 produit.",
103 104 "Deux requêtes minimum par boutique (HTML d'accueil + API).",
104 105 ]),
106 + "votresite": dict(
107 + titre="Connecteur Votresite.ca (Drupal + OpenCart)", module="votresite.py",
108 + endpoint="Boutique OpenCart montée sous `/boutique` (parfois `/produits`, "
109 + "`/shop`) : inventaire par `<mount>/sitemap.xml` sinon crawl des "
110 + "catégories `<mount>/fr` (`?limit=100&page=N`), puis fiche par "
111 + "fiche `…/<slug>-p<ID>/` (rendu 100 % serveur, aucune API JSON).",
112 + gotchas=[
113 + "**Plateforme québécoise** (scripts.votresite.ca) : vitrine Drupal 8 "
114 + "géré (thème `owebo-votresite`) + boutique OpenCart en sous-répertoire — "
115 + "le montage est détecté via le registre, la page d'accueil, puis "
116 + "`/boutique`/`/produits`.",
117 + "**Prix : le HTML d'abord, les meta en secours** — en solde, "
118 + "`twitter:data1` affiche le prix RÉGULIER ; le prix courant est le "
119 + "`<h2>…$</h2>` de la fiche et le prix barré le `<span>` "
120 + "`text-decoration: line-through` (→ `compare_at_price`).",
121 + "**Titre = dernier `<h1>` sans ancre** : le premier `<h1>` est le "
122 + "logo du site (un lien) sur plusieurs thèmes ; `og:title` peut être "
123 + "du bourrage de mots-clés (ex. lemieldabee.ca).",
124 + "**Dédup par ID produit** : le même `p<ID>` apparaît sous plusieurs "
125 + "chemins de catégorie (`-p361c37c45c44`).",
126 + "Les URLs d'images OpenCart contiennent espaces/accents bruts "
127 + "(`image/cache/catalog/…`) — encodées avant stockage.",
128 + ]),
105 129 "generic": dict(
106 130 titre="Connecteur générique (JSON-LD / microdata / OG)", module="generic.py",
107 131 endpoint="Sitemap → pages produit → extraction du balisage produit "
108 132