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
6 h agolast push
Python 38.4% HTML 30.3% TypeScript 17.2% CSS 11% JavaScript 3.2%

docs: refonte du README (pastilles + captures d écran à jour)

Simon-Pierre Boucher committed 1 mo ago (Aug 24, 2026) parent 33cd1ba

3 changed files +78 −216

modified README.md +78 −216
@@ -1,196 +1,80 @@
1 −<div align="center">
2 −
3 1 # Fabri·Ka
4 2
5 −### Tous les produits québécois. Un seul endroit.
6 −
7 −**[www.fabri-ka.com](https://www.fabri-ka.com)**
8 −
9 −![Python](https://img.shields.io/badge/Python-3.14-1E1B16?style=for-the-badge&logo=python&logoColor=C4532E)
10 −![FastAPI](https://img.shields.io/badge/FastAPI-API_+_SSR-1E1B16?style=for-the-badge&logo=fastapi&logoColor=C4532E)
11 −![React](https://img.shields.io/badge/React_18-Vite_+_TS-1E1B16?style=for-the-badge&logo=react&logoColor=C4532E)
12 −![SQLite](https://img.shields.io/badge/SQLite-FTS5-1E1B16?style=for-the-badge&logo=sqlite&logoColor=C4532E)
13 −![Firecrawl](https://img.shields.io/badge/Firecrawl-rendu_JS-1E1B16?style=for-the-badge&logoColor=C4532E)
14 −
15 −![Produits](https://img.shields.io/badge/produits_agr%C3%A9g%C3%A9s-301_534-234438?style=flat-square)
16 −![Boutiques connectées](https://img.shields.io/badge/boutiques_avec_produits-1_377-234438?style=flat-square)
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-9-234438?style=flat-square)
19 −![Régions](https://img.shields.io/badge/r%C3%A9gions_couvertes-17%2F17-234438?style=flat-square)
20 −![Sources](https://img.shields.io/badge/sources_de_d%C3%A9couverte-35%2B-234438?style=flat-square)
21 −
22 −![SEO](https://img.shields.io/badge/SEO-SSR_+_JSON--LD_+_sitemaps-C4532E?style=flat-square)
23 −![Pages indexables](https://img.shields.io/badge/pages_indexables-301_000%2B-C4532E?style=flat-square)
24 −![SSO](https://img.shields.io/badge/KA_ID-SSO_Groupe_KA-C4532E?style=flat-square)
25 −![Langue](https://img.shields.io/badge/fr--CA-d'abord-C4532E?style=flat-square)
26 −
27 −</div>
28 −
29 −![Aperçu de Fabri-Ka](docs/screenshot.png)
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.
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.**
40 4
41 −## Fonctionnalités
42 −
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.
5 +[![Site](https://img.shields.io/website?url=https%3A%2F%2Fwww.fabri-ka.com&style=flat-square&label=www.fabri-ka.com)](https://www.fabri-ka.com)
6 +![Nœud](https://img.shields.io/badge/n%C5%93ud-M4M64a-1f6feb?style=flat-square)
7 +![Port](https://img.shields.io/badge/port-8097-555?style=flat-square)
8 +![PM2](https://img.shields.io/badge/process-PM2-2b037a?style=flat-square)
9 +![Python](https://img.shields.io/badge/Python-FastAPI-3776ab?style=flat-square&logo=python&logoColor=white)
10 +![React](https://img.shields.io/badge/React_18-Vite_%2B_TS-61dafb?style=flat-square&logo=react&logoColor=black)
11 +![SQLite](https://img.shields.io/badge/SQLite-FTS5-003b57?style=flat-square&logo=sqlite&logoColor=white)
12 +![Groupe KA](https://img.shields.io/badge/Groupe-KA-b7f000?style=flat-square)
52 13
53 −### Galerie
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.
54 15
55 −| Accueil | Fiche produit |
56 −|---|---|
57 −| ![Accueil](docs/screenshots/accueil.png) | ![Fiche produit](docs/screenshots/produit.png) |
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.
58 17
59 −| Catalogue & filtres | Page catégorie (SEO programmatique) |
60 −|---|---|
61 −| ![Catalogue](docs/screenshots/catalogue.png) | ![Catégorie](docs/screenshots/categorie.png) |
62 −
63 −| Boutiques | Page boutique (landing) | Statistiques |
64 −|---|---|---|
65 −| ![Boutiques](docs/screenshots/boutiques.png) | ![Boutique](docs/screenshots/boutique.png) | ![Stats](docs/screenshots/stats.png) |
18 +## Captures d'écran
66 19
67 20 <p align="center">
68 − <img src="docs/screenshots/mobile.png" width="240" alt="Accueil mobile"/>
69 − &nbsp;&nbsp;
70 − <img src="docs/screenshots/mobile-produit.png" width="240" alt="Fiche produit mobile"/>
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">
71 23 </p>
72 24
73 −## Stack technique
74 −
75 −| Couche | Technologies |
76 −|---|---|
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 −```
105 −
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 |
117 −
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.
119 −
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).
25 +## Fonctionnalités
121 26
122 −**Performance** : **GZip** (‑80 % sur le HTML), `Cache-Control: immutable` sur les assets hashés, images `loading="lazy"` avec dimensions explicites, polices en `swap`.
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`).
123 36
124 −## API
37 +## Architecture
125 38
126 −| Endpoint | Description |
39 +| Composant | Rôle |
127 40 |---|---|
128 −| `GET /api/products?q=&category=&region=&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
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) |
141 48
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 |
49 +**Processus PM2 (production)** :
149 50
150 −Chaque classe est justifiée par une **évidence conservée** — jamais déduite du seul fait qu'une entreprise « semble » québécoise.
51 +| Processus | Commande | Rôle |
52 +|---|---|---|
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 |
151 56
152 −## Chiffres (2026-08-18, site live)
57 +## Structure du repo
153 58
154 −| Mesure | Valeur |
59 +| Répertoire | Contenu |
155 60 |---|---|
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).
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 |
166 68
167 −## Structure du projet
69 +## Développement (remote-first)
168 70
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 −```
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).
189 72
190 −## Démarrage local
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).
191 74
192 75 ```bash
193 −git clone https://git.spboucher.ai/fabri-ka.git && cd fabri-ka
76 +ssh M4M64a
77 +cd ~/fabri-ka
194 78
195 79 # Backend
196 80 python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
@@ -198,60 +82,38 @@ python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
198 82 # Frontend
199 83 cd frontend && npm install && npm run build && cd ..
200 84
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
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
208 89
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)
213 −```
214 −
215 −## Déploiement
216 −
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)**.
218 −
219 −**3 processus PM2 :**
90 +# Après un changement en prod
91 +pm2 restart fabri-ka-web # (ou fabri-ka-sync selon le changement)
220 92
93 +git add <fichiers> && git commit && git push origin main
221 94 ```
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 95
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).
96 +## Déploiement
232 97
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`.
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.
235 99
236 −## Principes
100 +## Écosystème Groupe KA
237 101
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.
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
243 115
244 116 ---
245 117
246 −<div align="center">
247 −
248 −**Simon-Pierre Boucher**
249 −
250 −[![Email](https://img.shields.io/badge/contact@spboucher.ai-1E1B16?style=for-the-badge&logo=minutemailer&logoColor=C4532E)](mailto:contact@spboucher.ai)
251 −[![Git](https://img.shields.io/badge/git.spboucher.ai-1E1B16?style=for-the-badge&logo=git&logoColor=C4532E)](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>
118 +© Groupe KA — Simon-Pierre Boucher · contact@spboucher.ai
119 +Ce repo vit sur **spbgit** ([git.spboucher.ai](https://git.spboucher.ai)).
added docs/screenshots/fabri-ka-desktop.png +0 −0

Binary file not shown.

added docs/screenshots/fabri-ka-mobile.png +0 −0

Binary file not shown.