Reapply "docs: refonte du README (pastilles + captures d écran à jour)"
This reverts commit b3a6a11dc9cb99a75362feca3b4be7682ffe958c.
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 | − | |
| 10 | − | |
| 11 | − | |
| 12 | − | |
| 13 | − | |
| 14 | − | |
| 15 | − | |
| 16 | − | |
| 17 | − | |
| 18 | − | |
| 19 | − | |
| 20 | − | |
| 21 | − | |
| 22 | − | |
| 23 | − | |
| 24 | − | |
| 25 | − | |
| 26 | − | |
| 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. | |
| 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 | +[](https://www.fabri-ka.com) | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 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 | −|  |  | | |
| 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 | −|  |  | | |
| 62 | − | |
| 63 | −| Boutiques | Page boutique (landing) | Statistiques | | |
| 64 | −|---|---|---| | |
| 65 | −|  |  |  | | |
| 18 | +## Captures d'écran | |
| 66 | 19 | |
| 67 | 20 | <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"/> | |
| 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=®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 | |
| 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 | −[](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> | |
| 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.