Revert "docs: refonte du README (pastilles + captures d écran à jour)"
This reverts commit 3cbf9574494ce8ad015e887d9661eadc4d984091.
3 changed files +216 −78
modified
README.md
+216 −78
@@ -1,80 +1,196 @@ | ||
| 1 | +<div align="center"> | |
| 2 | + | |
| 1 | 3 | # Fabri·Ka |
| 2 | 4 | |
| 3 | −**Le répertoire des produits québécois : plus de 300 000 produits de 1 377 boutiques d'ici, trouvables au même endroit.** | |
| 5 | +### Tous les produits québécois. Un seul endroit. | |
| 4 | 6 | |
| 5 | −[](https://www.fabri-ka.com) | |
| 6 | − | |
| 7 | − | |
| 8 | − | |
| 9 | − | |
| 10 | − | |
| 11 | − | |
| 12 | − | |
| 7 | +**[www.fabri-ka.com](https://www.fabri-ka.com)** | |
| 13 | 8 | |
| 14 | −**Fabri-Ka** est un **agrégateur de découverte de produits québécois** : **301 534 produits** provenant de **1 377 boutiques en ligne** du Québec (sur **3 507 boutiques vérifiées** au registre), couvrant les **17 régions administratives** de la province. Chaque produit renvoie vers la **boutique d'origine** — aucune vente sur Fabri-Ka : prix, photos et stocks appartiennent aux marchands sources. | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 15 | 14 | |
| 16 | −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** (35+ sources : certifications, associations, annuaires, marques régionales) recense les boutiques et les classe par **origine de fabrication (A–E)** avec évidence conservée ; des **connecteurs par plateforme ecommerce** — et non par site — aspirent les catalogues publics (le même code Shopify sert des centaines de boutiques, piloté par le registre `data/stores.json`) ; un **moteur de recherche plein-texte FTS5** les rend trouvables par catégorie, région, origine et prix. | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 17 | 21 | |
| 18 | −## Captures d'écran | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 19 | 26 | |
| 20 | −<p align="center"> | |
| 21 | − <img src="docs/screenshots/fabri-ka-desktop.png" width="640" alt="Accueil — desktop"> | |
| 22 | − <img src="docs/screenshots/fabri-ka-mobile.png" width="200" alt="Accueil — mobile"> | |
| 23 | −</p> | |
| 27 | +</div> | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | +--- | |
| 32 | + | |
| 33 | +## Description | |
| 34 | + | |
| 35 | +**Fabri-Ka** est le **répertoire des produits québécois** : un agrégateur de découverte qui recense **301 534 produits** provenant de **1 377 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. | |
| 36 | + | |
| 37 | +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 (**3 507 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**). | |
| 38 | + | |
| 39 | +> Contrairement à un agrégateur classique (1 connecteur / site), Fabri-Ka utilise **1 connecteur / plateforme ecommerce** : le même code **Shopify** sert des centaines de boutiques, piloté par le registre `data/stores.json` produit par la recherche. | |
| 24 | 40 | |
| 25 | 41 | ## Fonctionnalités |
| 26 | 42 | |
| 27 | −- **Recherche de produits** — plein-texte **FTS5 accent-insensible** sur 301 534 produits, filtres catégorie / région / origine / prix, tri, pagination, fiches riches (galerie, boutique, produits liés). | |
| 28 | −- **Répertoire de boutiques** — 1 377 boutiques avec produits, fiches enrichies : logo, région, plateforme, stats de prix, politique de livraison, catégories, boutiques similaires. | |
| 29 | −- **Taxonomie de 20 catégories** (mode, bijoux, épicerie fine, érable…) avec ~350 pages programmatiques SEO (`/categorie/erable`, `/region/monteregie`, combinaisons non vides). | |
| 30 | −- **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). | |
| 31 | −- **Statistiques** — tableau de bord `/stats` (module commun ka-stats) : totaux, médianes, histogrammes, ventilation régionale — et **rapports de marché PDF personnalisés** (catalogue de rapports, ReportBuilder, moteur kapdf/ReportLab). | |
| 32 | −- **SEO / SSR** — **301 000+ pages indexables** : HTML complet dès la première requête, JSON-LD schema.org (`Product`, `Offer`, `BreadcrumbList`, `OnlineStore`…), sitemaps exhaustifs (chunks de 40 000 URLs), 301/404/410 propres — jamais de soft-404. | |
| 33 | −- **KA ID (SSO)** — connexion au hub groupe-ka.com (JWT HS256) + favoris « Mon univers Ka » ; widget de chat **KA Agent**. | |
| 34 | −- **Mobile-first** — barre d'onglets, filtres en bottom sheet, galeries swipe, fr-CA d'abord. | |
| 35 | −- **Formulaire d'inscription** pour les marchands (`fabrika/inscriptions.py`). | |
| 43 | +- **Recherche de produits** — plein-texte **FTS5 accent-insensible** sur **301 534 produits**, filtres **catégorie / région / origine / prix**, tri, pagination, fiches riches (galerie, boutique, produits liés). | |
| 44 | +- **Répertoire de boutiques** — **1 377 boutiques** avec produits (sur **3 507 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. | |
| 45 | +- **Statistiques** — tableau de bord analytique `/stats` (module commun **ka-stats**) : totaux, médianes, histogrammes, ventilation régionale, croissance — et **rapport de marché PDF** généré à la volée (`/api/report.pdf`, moteur **kapdf**). | |
| 46 | +- **Catégories** — taxonomie de **20 catégories** (mode 38 k · bijoux 34 k · épicerie fine 29 k · …) avec **~350 pages programmatiques SEO** (`/categorie/erable`, `/region/monteregie`, combinaisons non vides). | |
| 47 | +- **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). | |
| 48 | +- **SEO / SSR** — **301 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). | |
| 49 | +- **KA ID (SSO)** + favoris **« Mon univers Ka »** synchronisés au hub **groupe-ka.com**. | |
| 50 | +- **Widget KA Agent** — bulle de chat Groupe KA (`ka-agent.js`). | |
| 51 | +- **Mobile-first** — barre d'onglets, filtres en bottom sheet, galeries swipe, CTA collant, PWA-lite, **fr-CA** d'abord. | |
| 36 | 52 | |
| 37 | −## Architecture | |
| 53 | +### Galerie | |
| 38 | 54 | |
| 39 | −| Composant | Rôle | | |
| 55 | +| Accueil | Fiche produit | | |
| 40 | 56 | |---|---| |
| 41 | −| `scripts/` (pipeline de découverte) | harvest → aggregate → verify → classify A–E → `data/stores.json` (3 507 boutiques QC vérifiées), enrichissements (contacts, livraison, géocodage, collections) | | |
| 42 | −| `fabrika/connectors/` | 9 connecteurs **par plateforme** : Shopify (`products.json`, transport curl anti-429), WooCommerce Store API, Wix Stores GraphQL, Squarespace `?format=json`, Square Online, Votresite.ca, Immunotec, générique (sitemap → JSON-LD/microdata/OG), Scrapfly/Firecrawl en secours anti-bot | | |
| 43 | −| `fabrika/ingest.py` + `schema.py` | boucle de sync : upsert par hash de contenu, retraits avec délai de grâce (2 syncs), journal `sync_log` par boutique | | |
| 44 | −| `fabrika/web.py` + `seo.py` | FastAPI : API JSON (`/api/products`, `/api/facets`…), rendu SEO serveur (head + contenu dans `#root`, hydratation React), service du build Vite | | |
| 45 | −| `fabrika/statsdash.py` + `report.py` + `kapdf.py` | tableau de bord stats et rapports PDF | | |
| 46 | −| Base de données | **SQLite + FTS5** : `data/fabrika.db` (produits, boutiques, sync_log) + caches (`enrich_cache/`, `verify_cache/`, `geocode_cache/`) | | |
| 47 | −| Frontend | React 18 + Vite + TypeScript, react-router, identité famille KA (tokens ka-ui) | | |
| 57 | +|  |  | | |
| 48 | 58 | |
| 49 | −**Processus PM2 (production)** : | |
| 59 | +| Catalogue & filtres | Page catégorie (SEO programmatique) | | |
| 60 | +|---|---| | |
| 61 | +|  |  | | |
| 50 | 62 | |
| 51 | −| Processus | Commande | Rôle | | |
| 63 | +| Boutiques | Page boutique (landing) | Statistiques | | |
| 52 | 64 | |---|---|---| |
| 53 | −| `fabri-ka-web` | `.venv/bin/python run.py serve 8097` | API + frontend + SSR SEO | | |
| 54 | −| `fabri-ka-sync` | `.venv/bin/python run.py watch 360` | resynchronisation des catalogues aux 6 h | | |
| 55 | −| `fabri-ka-ngrok` | `ngrok http --url=www.fabri-ka.com 8097` | tunnel vers le domaine public | | |
| 65 | +|  |  |  | | |
| 66 | + | |
| 67 | +<p align="center"> | |
| 68 | + <img src="docs/screenshots/mobile.png" width="240" alt="Accueil mobile"/> | |
| 69 | + | |
| 70 | + <img src="docs/screenshots/mobile-produit.png" width="240" alt="Fiche produit mobile"/> | |
| 71 | +</p> | |
| 56 | 72 | |
| 57 | −## Structure du repo | |
| 73 | +## Stack technique | |
| 58 | 74 | |
| 59 | −| Répertoire | Contenu | | |
| 75 | +| Couche | Technologies | | |
| 60 | 76 | |---|---| |
| 61 | −| `fabrika/` | paquet Python : connecteurs plateforme, ingestion, API/SSR, stats, rapports PDF, SSO | | |
| 62 | −| `frontend/` | SPA React 18 + Vite + TypeScript | | |
| 63 | −| `scripts/` | pipeline de découverte et d'enrichissement des boutiques (harvest, verify, classify, geocode…) | | |
| 64 | −| `data/` | `fabrika.db` (SQLite+FTS5), `stores.json` (registre), taxonomie, caches d'enrichissement | | |
| 65 | −| `docs/` | captures d'écran, docs des connecteurs, dossier de conformité (`CONFORMITE.md`) | | |
| 66 | −| `deliverables/` / `logs/` | exports produits par les scripts et journaux | | |
| 67 | −| `run.py` / `requirements.txt` | point d'entrée CLI (`sync`, `watch`, `serve`, `registry`) et dépendances backend | | |
| 77 | +| **Backend** | **Python 3.14** · **FastAPI** (API + SSR SEO + service du frontend) | | |
| 78 | +| **Base de données** | **SQLite + FTS5** — upsert par **hash de contenu**, retraits avec délai de grâce (2 syncs) | | |
| 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) · **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 | +| **Découverte** | **35+ sources** : sitemaps d'annuaires, API cachées de cartes (wpgmza, FacetWP), pagination htmx, sessions **Firecrawl** pour répertoires JS | | |
| 82 | +| **Comptes** | **KA ID** SSO (JWT HS256, stdlib pure) · favoris HMAC-SHA256 vers le hub central | | |
| 83 | +| **Prod** | **PM2** + **ngrok** sur le cluster **MacLustr** | | |
| 84 | + | |
| 85 | +### Architecture en 30 secondes | |
| 86 | + | |
| 87 | +```mermaid | |
| 88 | +flowchart LR | |
| 89 | + subgraph Discovery["Pipeline de découverte (scripts/)"] | |
| 90 | + A["35+ annuaires sources<br/>certifications · associations ·<br/>marques régionales · balayages"] --> B["harvest → aggregate →<br/>verify → classify A–E"] | |
| 91 | + B --> R[("stores.json<br/>3 507 boutiques QC")] | |
| 92 | + end | |
| 93 | + subgraph FabriKa["Plateforme (fabrika/)"] | |
| 94 | + R --> C["Connecteurs plateforme<br/>Shopify · Woo · Wix · Squarespace · Square ·<br/>générique (JSON-LD) · Scrapfly"] | |
| 95 | + C --> D[("SQLite + FTS5<br/>hash + diff")] | |
| 96 | + D --> E["API FastAPI<br/>/api/products · /api/facets"] | |
| 97 | + D --> S["Rendu serveur SEO<br/>HTML complet · JSON-LD ·<br/>sitemaps · 301/404/410"] | |
| 98 | + E --> F["React 18 + Vite<br/>recherche · filtres · fiches"] | |
| 99 | + S --> G["🕷 Googlebot & co."] | |
| 100 | + end | |
| 101 | + H["KA ID (SSO) + favoris<br/>hub groupe-ka.com"] <--> E | |
| 102 | + W["⏱ Watcher 6 h (PM2)"] -.-> C | |
| 103 | + F --> U["🍁 Acheteur local"] | |
| 104 | +``` | |
| 68 | 105 | |
| 69 | −## Développement (remote-first) | |
| 106 | +## SEO & rendu serveur — **301 000+ pages indexables** | |
| 107 | + | |
| 108 | +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). | |
| 109 | + | |
| 110 | +| Élément | Détail | | |
| 111 | +|---|---| | |
| 112 | +| **Title & meta description uniques** | Générés par page à partir des données réelles (compteurs, prix, boutique) | | |
| 113 | +| **Canonical + hreflang fr-CA** | Sur chaque page, querystring normalisée | | |
| 114 | +| **Open Graph + Twitter Card** | `og:image` = photo produit / couverture boutique | | |
| 115 | +| **JSON-LD schema.org** | `Product` + `Offer` (prix CAD, dispo, vendeur), `BreadcrumbList`, `OnlineStore`, `CollectionPage` + `ItemList`, `WebSite` + `SearchAction` | | |
| 116 | +| **Contenu HTML complet** | H1, stats, description, galerie (lazy + dimensions), grille de produits, maillage interne | | |
| 70 | 117 | |
| 71 | −La **source de vérité est le repo git sur le nœud M4M64a** (`~/fabri-ka`) — pas une copie laptop. Toute modification se fait sur le nœud via SSH : édition, build, redémarrage, puis commit/push depuis le nœud (agent forwarding actif). | |
| 118 | +**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. | |
| 72 | 119 | |
| 73 | −- Remote `origin` = **spbgit**, le git perso ([git.spboucher.ai](https://git.spboucher.ai)) : alias SSH **`gitsrv`** configuré sur le nœud → `gitsrv:srv/git/fabri-ka.git` (bare repo hébergé sur M3U96a). | |
| 120 | +**Sitemaps & robots** : `/robots.txt` → `/sitemap.xml` (index) → `sitemap-pages.xml` + `sitemap-boutiques.xml` + `sitemap-produits-{1..8}.xml` (**40 000 URLs/chunk**, `lastmod` réel, régénérés automatiquement, cache 1 h). | |
| 121 | + | |
| 122 | +**Performance** : **GZip** (‑80 % sur le HTML), `Cache-Control: immutable` sur les assets hashés, images `loading="lazy"` avec dimensions explicites, polices en `swap`. | |
| 123 | + | |
| 124 | +## API | |
| 125 | + | |
| 126 | +| Endpoint | Description | | |
| 127 | +|---|---| | |
| 128 | +| `GET /api/products?q=&category=®ion=&origin=&price_min=&price_max=&sort=&page=` | Recherche plein-texte + filtres, triée | | |
| 129 | +| `GET /api/products/{uid}` | Fiche produit (galerie, boutique, produits liés) | | |
| 130 | +| `GET /api/stores?region=&q=&with_products=` | Répertoire des boutiques (logo, région, plateforme) | | |
| 131 | +| `GET /api/stores/{id}` | Fiche boutique enrichie : stats de prix, catégories, boutiques similaires | | |
| 132 | +| `GET /api/facets` | Catégories/régions/origines avec compteurs | | |
| 133 | +| `GET /api/stats` · `GET /api/stats/extended` | Totaux, ventilation régionale · stats riches (médianes, histogrammes, croissance) | | |
| 134 | +| `GET /api/report.pdf` | Rapport de marché PDF — généré à la volée | | |
| 135 | +| `POST /api/sync` | Déclenche une synchronisation en arrière-plan | | |
| 136 | +| `GET /api/auth/ka/login` → `…/callback` · `GET /api/auth/me` · `POST /api/auth/logout` | SSO **KA ID** | | |
| 137 | +| `GET /api/favorites` · `POST /api/favorites/toggle` | Favoris « Mon univers Ka » (hub central) | | |
| 138 | +| `GET /robots.txt` · `GET /sitemap.xml` (+ sous-sitemaps) | Infrastructure SEO | | |
| 139 | + | |
| 140 | +## Classification d'origine | |
| 141 | + | |
| 142 | +| Classe | Signification | | |
| 143 | +|---|---| | |
| 144 | +| **A** | Fabriqué / cultivé / transformé au Québec | | |
| 145 | +| **B** | Conçu au Québec, fabriqué ailleurs | | |
| 146 | +| **C** | Détaillant québécois (revente) | | |
| 147 | +| **D** | Mixte | | |
| 148 | +| **E** | Incertain — à vérifier | | |
| 149 | + | |
| 150 | +Chaque classe est justifiée par une **évidence conservée** — jamais déduite du seul fait qu'une entreprise « semble » québécoise. | |
| 151 | + | |
| 152 | +## Chiffres (2026-08-18, site live) | |
| 153 | + | |
| 154 | +| Mesure | Valeur | | |
| 155 | +|---|---| | |
| 156 | +| Produits agrégés (catalogues complets) | **301 534** | | |
| 157 | +| Boutiques avec produits en ligne | **1 377** | | |
| 158 | +| Régions administratives couvertes | **17 / 17** | | |
| 159 | +| Boutiques québécoises actives vérifiées (registre) | **3 507** | | |
| 160 | +| — avec ecommerce détecté | 2 141 | | |
| 161 | +| Domaines candidats découverts et dédupliqués | 3 980 | | |
| 162 | +| Catégories | **20** (mode 38 k · bijoux 32 k · épicerie fine 28 k · …) | | |
| 163 | +| Pages indexables (produits + boutiques + programmatiques) | **301 000+** | | |
| 164 | + | |
| 165 | +Détails et méthodologie : [`deliverables/research_report.md`](deliverables/research_report.md) · stratégie de découverte continue : [`deliverables/discovery_strategy.md`](deliverables/discovery_strategy.md). | |
| 166 | + | |
| 167 | +## Structure du projet | |
| 168 | + | |
| 169 | +``` | |
| 170 | +fabri-ka/ | |
| 171 | +├── fabrika/ # plateforme | |
| 172 | +│ ├── web.py # API FastAPI + service du frontend + routes SEO | |
| 173 | +│ ├── seo.py # rendu serveur : meta, JSON-LD, sitemaps, 301/404/410 | |
| 174 | +│ ├── db.py # SQLite + FTS5, diff par hash, délai de grâce | |
| 175 | +│ ├── ingest.py # orchestration des syncs par boutique | |
| 176 | +│ ├── schema.py # modèles Product/Store, taxonomie 20 catégories, 17 régions | |
| 177 | +│ ├── report.py # rapport de marché PDF généré à la volée | |
| 178 | +│ ├── auth.py # SSO « KA ID » (JWT HS256, zéro dépendance) | |
| 179 | +│ ├── hubfav.py # favoris poussés au hub Groupe KA (HMAC) | |
| 180 | +│ ├── hubprofile.py # profil membre lu du hub | |
| 181 | +│ └── connectors/ # shopify · woocommerce · wix · squarespace · generic · scrapfly | |
| 182 | +├── frontend/ # React 18 + Vite + TS — 9 pages, PWA-lite, fr-CA | |
| 183 | +├── scripts/ # pipeline de découverte (harvest → verify → registry) | |
| 184 | +├── data/ # stores.json (registre) · fabrika.db · caches (non versionnés) | |
| 185 | +├── deliverables/ # rapport de recherche, CSV des boutiques, sources | |
| 186 | +├── docs/ # captures d'écran de ce README | |
| 187 | +└── run.py # CLI : sync · serve · watch | |
| 188 | +``` | |
| 189 | + | |
| 190 | +## Démarrage local | |
| 74 | 191 | |
| 75 | 192 | ```bash |
| 76 | −ssh M4M64a | |
| 77 | −cd ~/fabri-ka | |
| 193 | +git clone https://git.spboucher.ai/fabri-ka.git && cd fabri-ka | |
| 78 | 194 | |
| 79 | 195 | # Backend |
| 80 | 196 | python3 -m venv .venv && .venv/bin/pip install -r requirements.txt |
@@ -82,38 +198,60 @@ python3 -m venv .venv && .venv/bin/pip install -r requirements.txt | ||
| 82 | 198 | # Frontend |
| 83 | 199 | cd frontend && npm install && npm run build && cd .. |
| 84 | 200 | |
| 85 | −# Ingestion et service | |
| 86 | −.venv/bin/python run.py sync # toutes les boutiques connectables (ou : sync <store_id> …) | |
| 87 | −.venv/bin/python run.py registry # reconstruire data/stores.json depuis le pipeline | |
| 88 | −.venv/bin/python run.py serve 8097 # API + frontend | |
| 89 | − | |
| 90 | −# Après un changement en prod | |
| 91 | −pm2 restart fabri-ka-web # (ou fabri-ka-sync selon le changement) | |
| 201 | +# (optionnel) répertoires JS / sites anti-bot / SSO | |
| 202 | +cat > .env <<EOF | |
| 203 | +FIRECRAWL_API_KEY=fc-votre-cle | |
| 204 | +KA_SSO_SECRET=… # SSO KA ID (facultatif — le bouton n'apparaît pas sans) | |
| 205 | +KA_HUB_URL=https://www.groupe-ka.com | |
| 206 | +FABRIKA_BASE_URL=https://www.fabri-ka.com | |
| 207 | +EOF | |
| 92 | 208 | |
| 93 | −git add <fichiers> && git commit && git push origin main | |
| 209 | +# Ingestion puis service | |
| 210 | +.venv/bin/python run.py sync # toutes les boutiques connectables | |
| 211 | +.venv/bin/python run.py serve 8090 # → http://localhost:8090 | |
| 212 | +.venv/bin/python run.py watch 360 # resynchronisation en boucle (minutes) | |
| 94 | 213 | ``` |
| 95 | 214 | |
| 96 | 215 | ## Déploiement |
| 97 | 216 | |
| 98 | −En production sur le **nœud M4M64a** du cluster MacLustr (`~/fabri-ka`), servi sur le **port 8097** et exposé via un tunnel **ngrok** sur **[www.fabri-ka.com](https://www.fabri-ka.com)**. Trois processus PM2 : `fabri-ka-web` (serveur), `fabri-ka-sync` (boucle de sync aux 6 h), `fabri-ka-ngrok` (tunnel). La base `data/` de prod est resynchronisée en continu — ne jamais l'écraser. | |
| 217 | +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](https://www.fabri-ka.com)**. | |
| 99 | 218 | |
| 100 | −## Écosystème Groupe KA | |
| 219 | +**3 processus PM2 :** | |
| 101 | 220 | |
| 102 | −- [groupe-ka.com](https://www.groupe-ka.com) — portail | |
| 103 | −- [lou-ka.com](https://www.lou-ka.com) — logements à louer | |
| 104 | −- [immo-ka.com](https://www.immo-ka.com) — propriétés à vendre | |
| 105 | −- [vrai-prix.com](https://www.vrai-prix.com) — estimation immobilière | |
| 106 | −- [auto-ka.com](https://www.auto-ka.com) — véhicules | |
| 107 | −- [fabri-ka.com](https://www.fabri-ka.com) — produits québécois | |
| 108 | −- [food-ka.com](https://www.food-ka.com) — épicerie/alimentation | |
| 109 | −- [resto-ka.com](https://www.resto-ka.com) — restaurants | |
| 110 | −- [sorti-ka.com](https://www.sorti-ka.com) — sorties et événements | |
| 111 | −- [job-ka.com](https://www.job-ka.com) — emplois | |
| 112 | −- [crea-ka.com](https://www.crea-ka.com) — créateurs | |
| 113 | −- [trouve-ka.com](https://www.trouve-ka.com) — petites annonces | |
| 114 | −- [api-ka.com](https://www.api-ka.com) — API de données | |
| 221 | +``` | |
| 222 | +fabri-ka-web .venv/bin/python run.py serve 8097 # API + frontend + SSR SEO | |
| 223 | +fabri-ka-sync .venv/bin/python run.py watch 360 # resync aux 6 h | |
| 224 | +fabri-ka-ngrok ngrok http --url=www.fabri-ka.com 8097 # tunnel | |
| 225 | +``` | |
| 226 | + | |
| 227 | +Redéploiement : build + **`pm2 restart fabri-ka-web`** (la prod garde sa base `data/` — resynchronisée en continu, jamais écrasée). | |
| 228 | + | |
| 229 | +## Développement remote-first (IMPORTANT) | |
| 230 | + | |
| 231 | +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). | |
| 232 | + | |
| 233 | +- Remote `origin` = **spbgit** (git perso **[git.spboucher.ai](https://git.spboucher.ai)**), via l'alias SSH **`gitsrv`** : `gitsrv:srv/git/fabri-ka.git` — bare repo hébergé sur M3U96a. | |
| 234 | +- **Ne pas éditer de copies laptop** ; référence complète : `~/Desktop/cluster-skill/KA-REMOTE-DEV.md`. | |
| 235 | + | |
| 236 | +## Principes | |
| 237 | + | |
| 238 | +1. **Politesse** — throttle global par plateforme (Shopify : **0,7 s/req** toutes boutiques confondues), délais entre requêtes, User-Agent identifié. | |
| 239 | +2. **Fidélité** — aucun prix inventé ; entités HTML décodées ; si la source ne publie pas une donnée, elle est `null`. | |
| 240 | +3. **Traçabilité** — chaque produit renvoie vers la **boutique d'origine** ; chaque boutique conserve sa provenance de découverte et son évidence d'origine. | |
| 241 | +4. **Robustesse** — une boutique qui casse n'affecte jamais les autres ; journal `sync_log` avec raison d'échec par boutique. | |
| 242 | +5. **Trouvabilité** — tout ce qui existe dans la base existe pour Google : HTML complet, données structurées, sitemaps exhaustifs, jamais de soft-404. | |
| 115 | 243 | |
| 116 | 244 | --- |
| 117 | 245 | |
| 118 | −© Groupe KA — Simon-Pierre Boucher · contact@spboucher.ai | |
| 119 | −Ce repo vit sur **spbgit** ([git.spboucher.ai](https://git.spboucher.ai)). | |
| 246 | +<div align="center"> | |
| 247 | + | |
| 248 | +**Simon-Pierre Boucher** | |
| 249 | + | |
| 250 | +[](mailto:contact@spboucher.ai) | |
| 251 | +[](https://git.spboucher.ai) | |
| 252 | + | |
| 253 | +Un service **[Groupe Ka](https://www.groupe-ka.com)** | |
| 254 | + | |
| 255 | +© 2026 Simon-Pierre Boucher — tous droits réservés. | |
| 256 | + | |
| 257 | +</div> | |
deleted
docs/screenshots/fabri-ka-desktop.png
+0 −0
Binary file not shown.
deleted
docs/screenshots/fabri-ka-mobile.png
+0 −0
Binary file not shown.