# Forma·Ka
### Toutes les formations du Québec. Un seul endroit.
**[www.forma-ka.com](https://www.forma-ka.com)**











*Agrégateur indépendant de formations dans la province de Québec — cours en
ligne, cours universitaires et collégiaux, séminaires, ateliers, conférences,
certifications et bootcamps — chaque formation avec sa fiche détaillée
standardisée et un lien direct vers la page originale de l'établissement.
Toujours à jour, automatiquement.*
**Auteur : Simon-Pierre Boucher — [contact@spboucher.ai](mailto:contact@spboucher.ai)**
---
## Sommaire
1. [Visite guidée en 10 captures](#visite-guidée-en-10-captures)
2. [Pourquoi Forma-Ka ?](#pourquoi-forma-ka-)
3. [Fonctionnalités](#fonctionnalités)
4. [Architecture](#architecture)
5. [Le pipeline d'ingestion en détail](#le-pipeline-dingestion-en-détail)
6. [Les backends de fetch (chaîne résiliente)](#les-backends-de-fetch-chaîne-résiliente)
7. [Le schéma `Formation`](#le-schéma-formation)
8. [API & routes](#api--routes)
9. [Données & sources agrégées](#données--sources-agrégées)
10. [Ajouter un connecteur](#ajouter-un-connecteur)
11. [Démarrage rapide](#démarrage-rapide)
12. [Tests](#tests)
13. [Déploiement (production)](#déploiement-production)
14. [Dépôt & développement remote-first](#dépôt--développement-remote-first)
15. [Confidentialité](#confidentialité)
16. [Écosystème Groupe Ka](#écosystème-groupe-ka)
17. [Contact](#contact)
---
## Visite guidée en 10 captures
*Captures du site en production ([www.forma-ka.com](https://www.forma-ka.com)),
prises le 2026-08-28 en 1440 × 900 — plus une vue mobile 390 px. Les fichiers
sont dans
[`docs/screenshots/`](docs/screenshots/) (voir aussi
[`manifest.txt`](docs/screenshots/manifest.txt) pour la correspondance
capture → URL).*
### 1 · Accueil — le moteur de recherche

La page d'accueil (`/`) donne le ton « editorial sharp » : gros titres Space
Grotesk, surlignage ambré **#ffd54d**, ombres décalées, ticker en continu des
types de formations. On y trouve les compteurs en direct (**4 932 formations
actives · 135 gratuites · 3 556 en ligne · 18 établissements**), la barre de
recherche (sujet, sigle, compétence…), les filtres **Domaine / Mode / Ville /
Plus de filtres** et les pastilles de filtre rapide par type (Cours
universitaire, Formation continue, Cours collégial, Atelier, Conférence,
Séminaire, Webinaire, Gratuites…). En bas, la bannière de témoins rappelle la
philosophie : aucun traceur publicitaire, préférences en localStorage.
### 2 · Statistiques — portrait en direct de l'offre québécoise

La page `/stats` dresse le portrait en direct des formations actives, tous
établissements confondus : compteurs globaux (prix moyen affiché **858 $**,
durée moyenne **14 h**), répartition **par type de formation** (2 268 cours
universitaires, 2 058 formations continues, 118 cours collégiaux, 112 ateliers,
104 cours en ligne, 98 conférences, 80 séminaires, 41 webinaires, 27
programmes, 22 certifications, 4 bootcamps) et journal des **synchronisations
récentes** par source (trouvées / ajoutées / modifiées / retirées + état OK).
### 3 · Sources agrégées — le registre des établissements

La page `/sources` expose le registre `data/sources.json` enrichi en direct :
chaque établissement avec son type d'offre, son statut de connecteur
(**CONNECTÉ**), le nombre de formations actives et l'horodatage de la dernière
synchronisation. C'est la vitrine de transparence de Forma-Ka : on voit d'où
viennent les données et quand elles ont été rafraîchies.
### 4 · Confidentialité — « Votre vie privée, simplement. »

La page `/confidentialite` détaille l'approche minimaliste : aucun compte
utilisateur, aucun pixel publicitaire, aucun témoin tiers. Le seul stockage est
le localStorage du navigateur (choix de consentement, filtres de recherche),
avec un bouton « Modifier mes choix de témoins » accessible en tout temps.
### 5 · Fiche formation — le détail d'abord (Isarta · Data Studio)

Une fiche `/formation/:uid` (ici `isarta:data-studio`) montre la philosophie
« détail d'abord » : fil d'Ariane par catégorie, **plan de la formation**
complet (11 points), bloc **Admission / clientèle visée**, colonne des
**thèmes** et des **formations similaires** (avec type, mode, durée, prix et
source), puis le contenu original signé par la source. Chaque fiche renvoie
vers la page originale de l'établissement.
### 6 · Fiche formation — les recommandations « Formations similaires »

Le cœur d'une fiche vu de près : à gauche le **plan de la formation** point
par point et le bloc **Admission / clientèle visée** ; à droite la colonne de
recommandations **Formations similaires**, calculée par l'API (même catégorie,
même source, thèmes proches) avec pour chacune son type, son mode, sa durée et
son prix — un vrai moteur de découverte entre les 4 900+ fiches.
### 7 · Accueil — la grille de résultats

L'accueil, défilé jusqu'à la grille : cartes de formation en 3 colonnes avec
badge de type (Formation continue, Atelier…), établissement, titre, sigle,
mode (présentiel / en ligne) et durée, date de début (« Débute le 3 septembre
2026 ») et traitement franc du prix — **« Prix non affiché »** assumé (prix
optionnel), **« Gratuit »** mis en valeur, sinon le montant.
### 8 · Accueil — cartes illustrées & pagination (411 pages)

Plus bas sur l'accueil : les cartes reprennent les visuels originaux des
établissements (Institut de leadership, Événements Les Affaires…) avec prix
affiché (395 $, 545 $, 945 $), mode et ville. En pied de grille, la
**pagination** — « Page 1 de 411 — 4 930 formations » à 12 fiches par page —
puis le pied de page sombre avec la mission de l'agrégateur.
### 9 · Fiche formation en mobile (390 px)

La même fiche Data Studio sur téléphone : menu hamburger, ticker conservé,
fil d'Ariane et plan de la formation qui se replient proprement sur une
colonne — le socle mobile du Groupe Ka (zones tactiles, safe-area, PWA
installable) appliqué à Forma-Ka.
### 10 · Fiche événement — prix optionnel, dates offertes (CRHA · 5 à 7 estival)

Deuxième exemple de fiche (`crha:202609035@7Lanaudiere`) qui illustre la
souplesse du schéma : un événement de réseautage RH **sans prix affiché**
(le prix est optionnel dans Forma-Ka), avec ses **dates offertes** (3 septembre
2026), ses **infos pratiques** (établissement, sigle, horaire affiché, date de
synchronisation) et ses thèmes régionaux (Comité régionale de Lanaudière).
### Galerie mobile & desktop (2026-08-25)
*Captures WebP précédentes (mobile 390 × 844 · desktop 1440 × 900), conservées
dans [`docs/screenshots/mobile/`](docs/screenshots/mobile/) et
[`docs/screenshots/desktop/`](docs/screenshots/desktop/).*
 Accueil mobile |
 Fiche — détail d'abord |
 Stats mobile |
 Menu mobile |
> 🗄️ Les toutes premières captures (PNG) sont archivées dans
> [`docs/archive/`](docs/archive/).
---
## Pourquoi Forma-Ka ?
Chercher une formation au Québec, c'est ouvrir des dizaines de sites —
universités, cégeps, firmes de formation, organisateurs d'événements — chacun
avec sa navigation et son format. **Forma-Ka renverse le problème** : un
connecteur dédié par établissement visite chaque site, normalise chaque
formation dans un schéma unique et détecte les changements en continu.
> Les sites de formation n'offrent pas de webhooks. Forma-Ka en reproduit
> l'équivalent : **synchronisation périodique + hachage de contenu** → ajouts,
> mises à jour et retraits détectés automatiquement. Une formation qui
> disparaît du site source disparaît de Forma-Ka (après une période de grâce
> de 2 synchronisations).
**Philosophie** : contrairement à un agrégateur de produits, **le prix est
optionnel** (un cours universitaire n'affiche pas de prix) — ce qui compte, ce
sont les **détails** de chaque formation : description complète, objectifs
d'apprentissage, plan de cours, préalables, clientèle visée, durée,
crédits/UEC, mode de diffusion, dates offertes.
## Fonctionnalités
- **Recherche plein texte** (sujet, sigle, compétence) combinable avec les
filtres **domaine** (Informatique, Gestion, RH, Marketing…), **type**
(cours universitaire, formation continue, atelier, séminaire, webinaire,
certification, bootcamp…), **mode** (en ligne, présentiel, hybride,
asynchrone), **ville**, **langue**, **niveau**, **gratuit**, **prix maximal**
et **date de début** ;
- **Fiches détaillées standardisées** : description, objectifs, plan de cours,
préalables, clientèle visée, durée (texte + heures), crédits/UEC, sigle,
formateur, dates offertes, prix (optionnel, avec mention « à partir de »),
thèmes, formations similaires, lien direct vers la source ;
- **Statistiques en direct** (`/stats`) : portrait global + journal des
synchronisations par source ;
- **Registre des sources** (`/sources`) : statut du connecteur, volume,
dernière synchro ;
- **Ticker en continu** des types de formations en tête de chaque page ;
- **PWA installable** (manifest + thème clair, accent ambré `#ffd54d`),
pagination 12 par page, feuillet mobile (« bottom sheet ») pour les filtres ;
- **Aucun traceur** : consentement localStorage, page confidentialité dédiée ;
- **Mise à jour automatique** toutes les 6 h (watcher PM2) avec détection de
dérive des connecteurs.
## Architecture
```mermaid
flowchart LR
subgraph Sources["18 établissements de formation"]
S1["ÉTS Formation · TÉLUQ · ULaval
McGill · HEC · UQAM · Technologia
AFI · Cégep à distance · Les Affaires
… un connecteur par site"]
end
subgraph FormaKa["Forma-Ka"]
C["Connecteurs
1 adaptateur / site"] --> N["Normalisation
schéma Formation unique"]
N --> D[("SQLite
hash + diff + grâce")]
D --> A["FastAPI
/api/formations · /api/facets"]
A --> F["React 18 + Vite
PWA mobile · thème clair ambré"]
end
W["⏱ Watcher périodique
(PM2, 6 h)"] -.-> C
S1 --> C
F --> U["🎓 Apprenant"]
```
| Couche | Rôle | Fichiers |
|---|---|---|
| **Connecteurs** | 1 module Python par établissement : HTML rendu serveur, API JSON internes (Shopify `products.json`, WordPress REST, Gatsby `page-data`, Destiny One…), JSON-LD schema.org (`Course`/`Event`), chaîne anti-bot résiliente pour les sites difficiles | `formaka/connectors/*.py` |
| **Chaîne résiliente** | Escalade automatique direct → proxy résidentiel → anti-bot géré → déblocage premium quand un site se ferme (403/429/503, Cloudflare…) | `formaka/connectors/_resilient.py` |
| **Schéma** | `Formation` standardisée : type, catégorie, mode, description, objectifs, plan, préalables, durée, crédits/UEC, sessions, prix *(optionnel)* | `formaka/schema.py` |
| **Normalisation** | Couche commune : nettoyage de texte, types/modes/langues canoniques, prix, durées en heures, dates FR → ISO, extraction de détails (niveau, UEC…) | `formaka/normalize.py` |
| **Moteur de diff** | Upsert par hash de contenu — nouveau / modifié / disparu (période de grâce de 2 synchros), détection de dérive des connecteurs, cache des fiches | `formaka/db.py`, `formaka/ingest.py` |
| **API** | Filtres type / catégorie / mode / ville / langue / niveau / gratuit / prix / source / recherche, facettes, stats, déclenchement de synchro | `formaka/web.py` |
| **Frontend** | Design « editorial sharp » : Space Grotesk, ombres décalées, accent ambré `#ffd54d`, ticker en continu, feuillet mobile, pagination 12/page, PWA installable | `frontend/` |
### Structure du dépôt
```
forma-ka/
├── run.py # point d'entrée : sync | watch | serve
├── requirements.txt # fastapi, uvicorn, requests, beautifulsoup4
├── formaka/
│ ├── schema.py # dataclass Formation + finalize()
│ ├── normalize.py # normalisation commune (texte, prix, dates…)
│ ├── ingest.py # pipeline sync/watch (diff + grâce + journal)
│ ├── db.py # SQLite : formations, detail_cache, sync_log
│ ├── web.py # FastAPI : /api/* + service du frontend bâti
│ └── connectors/ # 18 connecteurs + base.py + _resilient.py
├── frontend/ # React 18 + Vite + TypeScript (PWA)
│ └── src/pages/ # Home, Formation, Stats, Sources, Privacy
├── data/
│ ├── sources.json # registre des établissements (versionné)
│ └── formaka.db # base SQLite (NON versionnée)
├── docs/screenshots/ # visite guidée (JPG) + galeries webp
└── tests/ # pytest (normalisation)
```
## Le pipeline d'ingestion en détail
1. **Découverte** — le registre des connecteurs est **auto-découvrant** :
chaque module de `formaka/connectors/` qui définit une classe héritant de
`BaseConnector` avec un `source_id` est enrôlé automatiquement.
2. **Collecte** — `fetch()` liste les formations du site (listing HTML, API
JSON interne, sitemap…), puis visite les pages de détail au besoin.
3. **Cache des fiches** — les pages de détail sont mises en cache dans la base
(`detail_cache`) avec une **clé hebdomadaire** : une page n'est revisitée
que si elle est nouvelle, modifiée, ou quand la semaine ISO change. Les
synchros intermédiaires sont donc rapides et économes.
4. **Normalisation** — `Formation.finalize()` applique la couche commune
(types/modes/langues canoniques, prix depuis le libellé, durée en heures,
dates françaises → ISO, extraction de niveau/UEC/crédits) sans jamais
écraser une valeur explicite du connecteur.
5. **Diff & grâce** — chaque fiche a un `content_hash` SHA-256 ; l'upsert ne
touche que ce qui a changé. Une formation absente du site source est
retirée après **2 synchros consécutives** d'absence (période de grâce
contre les listings instables).
6. **Journal & dérive** — chaque synchro est journalisée (`sync_log` :
trouvées / ajoutées / modifiées / retirées + taux de champs nuls) ; une
chute anormale du volume ou une explosion des champs vides signale une
dérive du connecteur (site remanié) visible sur `/stats` et `/sources`.
## Les backends de fetch (chaîne résiliente)
Historiquement, `BaseConnector.fetch_html()` enchaînait trois backends :
1. **requests direct** — sites rendus serveur (rapide, gratuit) ;
2. **Scrapfly** (`SCRAPFLY_API_KEY`) — contournement anti-bot (`asp`), rendu
JavaScript (`render_js`), géolocalisation canadienne ;
3. **Firecrawl** (`FIRECRAWL_API_KEY`) — rendu JS de repli, formats
html/markdown.
Cette chaîne est désormais renforcée par la **chaîne anti-bot résiliente
commune du Groupe KA** (`formaka/connectors/_resilient.py`) : quand un site
jusque-là ouvert déploie un anti-bot (Cloudflare, Akamai, Incapsula,
PerimeterX) ou renvoie 403/429/503, la requête directe n'échoue plus
silencieusement — elle **escalade automatiquement** :
1. **Direct** — session du connecteur (`curl_cffi` avec empreinte de
navigateur si disponible, sinon `requests`) ;
2. **Proxy résidentiel** — IP résidentielle canadienne propre ;
3. **Scrapfly (ASP)** — bypass anti-bot géré + rendu JS optionnel ;
4. **Bright Data (Web Unlocker)** — déblocage premium, dernier recours.
Le premier backend qui renvoie un 200 non vide gagne ; si tous échouent, la
dernière réponse est renvoyée telle quelle pour que le connecteur journalise
l'échec normalement (aucun blocage silencieux). Les clés d'API vivent dans
`.env` (jamais versionné).
## Le schéma `Formation`
Chaque connecteur, peu importe le site source, produit des objets `Formation`
(`formaka/schema.py`) :
| Groupe | Champs |
|---|---|
| **Identité** | `source`, `external_id`, `url` → `uid = source:external_id` |
| **Classement** | `title`, `training_type`, `category`, `tags`, `level`, `language` |
| **Diffusion** | `mode` (en ligne / présentiel / hybride / asynchrone), `city`, `start_date` (ISO), `sessions[]`, `schedule_label`, `duration`, `duration_hours` |
| **Contenu** | `description`, `objectives[]`, `program[]` (plan de cours), `prerequisites`, `audience`, `instructor`, `code` (sigle), `images[]` |
| **Valeur** | `price` *(optionnel — `None` = non affiché, c'est normal !)*, `price_label` (texte original), `is_free`, `credits` (« 3 crédits », « 1,4 UEC »), `credential` |
| **Technique** | `details` (JSON structuré dérivé), `content_hash()` (SHA-256 pour la détection de changements) |
## API & routes
### API REST (FastAPI)
| Point d'accès | Description |
|---|---|
| `GET /api/formations` | Liste filtrable (`training_type`, `category`, `mode`, `city`, `language`, `level`, `source`, `free`, `price_max`, `starts_after`, `q`, `sort`, `limit`, `offset`) |
| `GET /api/formations/{uid}` | Fiche complète + historique de prix + formations similaires |
| `GET /api/facets` | Valeurs distinctes pour construire les filtres |
| `GET /api/sources` | Registre des établissements + état de synchro (`active_formations`, `last_sync`) |
| `GET /api/stats` | Portrait global (totaux, moyennes, répartition par type) + journal des synchros |
| `POST /api/sync` | Déclenche une synchronisation en arrière-plan |
### Routes du frontend (SPA React Router)
| Route | Page |
|---|---|
| `/` | Accueil — recherche, filtres, compteurs en direct |
| `/formation/:uid` | Fiche détaillée (ex. `/formation/isarta:data-studio`) |
| `/stats` | Statistiques en direct |
| `/sources` | Registre des sources agrégées |
| `/confidentialite` | Politique de confidentialité & témoins |
| `*` | Page 404 (boussole) |
Le backend sert aussi le frontend bâti (`frontend/dist`) : `/assets` en
statique + rattrapage SPA sur toutes les autres routes.
## Données & sources agrégées
**18 établissements connectés — 4 932 formations actives** (relevé du
2026-08-28) :
| Établissement | Offre | Formations | Région |
|---|---|---:|---|
| Université Laval — Formation à distance | Cours universitaires à distance, hybrides et comodaux | 1 757 | Québec (à distance / hybride) |
| Technologia | Formation professionnelle — TI, IA, gestion | 590 | Montréal / Québec |
| Université TÉLUQ | Cours universitaires 100 % à distance, tous cycles | 511 | Québec (à distance) |
| AFI par Edgenda | Formation professionnelle — TI, leadership | 358 | Québec / Montréal |
| ÉTS Formation | Formation continue + UEC — technologie, construction, gestion, RH | 296 | Montréal |
| Versalys | Bureautique, TI, langues | 257 | Montréal · Québec · Laval · Brossard |
| McGill School of Continuing Studies | Formation continue (anglais) | 197 | Montréal |
| Isarta Formations | Marketing, communications, RH | 189 | Montréal (virtuel) |
| CRHA — Espace Formation | Formations et événements RH | 180 | Québec (province) — surtout en ligne |
| Événements Les Affaires | Conférences et webinaires d'affaires | 139 | Montréal / Québec / en ligne |
| Cégep à distance | Cours collégiaux à distance | 118 | Québec (en ligne) |
| École des dirigeant(e)s HEC Montréal | Séminaires et certifications pour cadres | 93 | Montréal |
| ITHQ — Ateliers et formations | Ateliers vins/cuisine + hôtellerie | 78 | Montréal (+ province) |
| Formation continue UQAM | Formation continue universitaire — UEC, séminaires | 49 | Montréal |
| École des entrepreneurs du Québec | Formations entrepreneur·e·s (souvent gratuites) | 48 | Montréal + en ligne |
| Institut de leadership | Certifications et programmes en leadership | 37 | Montréal (+ cohortes en ligne) |
| AlphaNumérique | Littératie numérique — gratuit | 29 | Québec (en ligne) |
| Le Wagon Montréal | Bootcamps dev web / data / IA | 4 | Montréal |
Répartition par type : **2 268** cours universitaires · **2 058** formations
continues · **118** cours collégiaux · **112** ateliers · **104** cours en
ligne · **98** conférences · **80** séminaires · **41** webinaires · **27**
programmes · **22** certifications · **4** bootcamps.
Le registre vit dans [`data/sources.json`](data/sources.json) (versionné) ;
la base SQLite (`data/formaka.db`) est locale et reconstruite par `sync`.
## Ajouter un connecteur
1. Créer `formaka/connectors/.py` : une classe héritant de
`BaseConnector`, définir `source_id` et implémenter
`fetch() -> list[Formation]`. Le registre est **auto-découvrant** — rien
d'autre à modifier.
2. Ajouter l'entrée correspondante dans `data/sources.json`.
3. Tester : `.venv/bin/python run.py sync `.
```python
class MonEcoleConnector(BaseConnector):
source_id = "mon_ecole"
def fetch(self) -> list[Formation]:
html = self.fetch_html(LIST_URL) # direct -> chaîne résiliente
...
return [Formation(source=self.source_id, external_id=..., url=...,
title=..., description=..., objectives=[...], ...)]
```
## Démarrage rapide
```bash
git clone https://git.spboucher.ai/forma-ka.git && cd forma-ka
# Backend
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
# Frontend
cd frontend && npm install && npm run build && cd ..
# Clés des backends de scraping (sites JavaScript / anti-bot) — jamais versionnées
cat > .env < http://localhost:8080
.venv/bin/python run.py watch 360 # boucle de synchro (défaut : toutes les 6 h)
```
## Tests
```bash
.venv/bin/python -m pytest tests/ -q
```
## Déploiement (production)
| Élément | Valeur |
|---|---|
| **Nœud** | `M3U96a` (Mac Studio, cluster MacLustr) — `~/apps/forma-ka` |
| **Port** | `8110` |
| **Processus PM2** | `forma-ka` (API + frontend, `run.py serve 8110`) · `forma-ka-sync` (`run.py watch 360` → synchro toutes les 6 h) · `forma-ka-ngrok` (tunnel) |
| **Domaine** | [www.forma-ka.com](https://www.forma-ka.com) via ngrok |
| **Base** | `data/formaka.db` (SQLite, locale au nœud) |
| **Résilience** | PM2 avec redémarrage automatique + `pm2 startup` (launchd) |
```bash
# Sur le nœud (lecture seule — l'état de référence)
pm2 ls | grep forma-ka
curl -s localhost:8110/api/stats | head -c 300
```
## Dépôt & développement remote-first
La **source de vérité est le dépôt git sur le nœud de déploiement**
(`M3U96a:~/apps/forma-ka`), pas une copie locale. Le remote `origin` est le
git personnel **spbgit** (git.spboucher.ai) — dépôt nu
`~/srv/git/forma-ka.git` hébergé sur M3U96a.
Cycle de travail : éditer sur le nœud via SSH → `npm run build` (frontend) →
`pm2 restart forma-ka` → `git add/commit/push origin main` **sur le nœud**
(agent forwarding actif).
Ce qui n'est **jamais versionné** (voir [`.gitignore`](.gitignore)) : la base
SQLite et les caches (`data/`, sauf `sources.json` déjà suivi), les secrets
(`.env*`), les environnements (`.venv/`, `node_modules/`), les artefacts de
build (`frontend/dist/`) et les journaux.
## Confidentialité
Forma-Ka ne collecte **rien qui identifie l'utilisateur** : pas de compte, pas
de formulaire d'inscription, pas de pixel publicitaire, pas de témoin tiers,
aucune donnée vendue. Le seul stockage est le **localStorage** du navigateur
(choix de consentement, filtres, préférences d'affichage), modifiable en tout
temps via « Gérer mes témoins ». Détails : page
[`/confidentialite`](https://www.forma-ka.com/confidentialite).
## Écosystème Groupe Ka
Forma-Ka fait partie du **Groupe Ka** ([groupe-ka.com](https://www.groupe-ka.com)),
la famille d'agrégateurs indépendants du Québec — notamment
[Lou-Ka](https://www.lou-ka.com) (logements),
[Immo-Ka](https://www.immo-ka.com) (propriétés),
[Vrai-Prix](https://www.vrai-prix.com) (épicerie),
[Auto-Ka](https://www.auto-ka.com) (véhicules),
[Food-Ka](https://www.food-ka.com), [Resto-Ka](https://www.resto-ka.com),
[Sorti-Ka](https://www.sorti-ka.com) (sorties),
[Job-Ka](https://www.job-ka.com) (emplois),
[Trouve-Ka](https://www.trouve-ka.com) (recherche),
[Créa-Ka](https://www.crea-ka.com) (créateurs),
[Fabri-Ka](https://www.fabri-ka.com) (produits d'ici) et
[Ka·Stats](https://www.ka-stats.com) (statistiques du Québec).
Même ADN partout : connecteurs dédiés, schéma standardisé, diff par hachage,
fiches détaillées, respect de la vie privée — et le mécanisme de Forma-Ka est
directement adapté de celui de Lou-Ka.
## Contact
**Simon-Pierre Boucher**
[contact@spboucher.ai](mailto:contact@spboucher.ai) · [www.forma-ka.com](https://www.forma-ka.com)
© 2026 Simon-Pierre Boucher — tous droits réservés.