Job·Ka
Tous les emplois des employeurs québécois
Les grands sites d'emploi mélangent annonces payantes, doublons repostés et offres mortes. L'offre originale — celle de la page carrière de l'employeur — est la seule source fiable. Job·Ka se branche directement sur les systèmes de recrutement (ATS) des employeurs québécois : 1 104 connecteurs employeurs directs sur 23 plateformes ATS (Workday, SmartRecruiters, Greenhouse, Dayforce, Breezy, Workable, Lever, Ashby, BambooHR, JazzHR, Recruitee, ADP WFN, Zoho Recruit, SuccessFactors, Njoyn, Teamtailor, WP Job Manager, iCIMS, Taleo Business Edition, Taleo, UltiPro/UKG, Digital Recruiters, Workland/réseau Atlas + sites carrières maison), complétés par 3 portails publics (Guichet-Emplois, Jobillico, Espresso-Jobs) — l'offre directe gagne toujours.
Résultat en base (au 2026-08-28) : 22 634 offres actives de 1 733 employeurs (1 048 sources actives), dont 21 243 offres directes et 7 114 avec salaire affiché (moyenne 61 681 $/an, médiane 57 325 $/an) — salaires normalisés en $/h et $/an, jamais inventés. Chaque offre est traçable à sa source et la candidature se fait chez l'employeur. Pour qui ? Les chercheurs d'emploi québécois qui veulent l'inventaire réel, à jour et transparent, des postes affichés dans la province — resynchronisé jour et nuit.
Chiffres clés (live sur /api/stats, vérifiés au 2026-08-28)
| Métrique | Valeur |
|---|---|
| Offres actives | 22 634 (129 doublons inter-sources masqués, 570 en quarantaine qualité) |
| Offres directes (pages carrières / ATS) | 21 243 — de 1 132 employeurs directs |
| Offres portails (complément) | 1 959 |
| Employeurs | 1 733 |
| Sources actives | 1 048 (registre : 1 108 entrées dont 1 en modération ; 1 104 employeurs directs connectés via 23 plateformes ATS + 3 portails + dépôt direct) |
| Avec salaire affiché | 7 114 — salaire moyen affiché ≈ 61 681 $/an (médiane 57 325 $/an) |
| Télétravail | 1 044 |
| Offres géocodées (carte) | 21 044 |
| Top villes | Montréal 8 176 · Québec 3 908 · Laval 769 · Dorval 720 |
| Top catégories | TI 2 802 · Santé 2 428 · Service à la clientèle 1 402 · Ventes 1 338 |
Visite guidée
Captures du 2026-08-28 (desktop 1440×900) — design « éditorial premium ». Chaque capture pointe vers la page réelle sur www.job-ka.com.
1. Accueil — job-ka.com
La porte d'entrée : recherche plein texte + filtres (ville, catégorie, salaire, télétravail…), chiffres clés live tirés de /api/stats et offres récentes. Le badge « Offre directe » distingue immédiatement les offres captées sur la page carrière de l'employeur.
2. Répertoire des villes — /villes
Toutes les villes du Québec où des offres sont actives, avec leur volume — des pages SEO programmatiques rendues en HTML côté serveur (/ville/{slug}), indexables et rapides.
3. Carte des offres — /carte
Les 21 044 offres géocodées sur une carte MapLibre GL (sans jeton), alimentée par GET /api/jobs.geojson. Géocodage Nominatim + repli officiel Adresses Québec (MERN), validé par bounding box provinciale — jamais inventé.
4. Sources — /sources
La transparence au premier plan : le registre public des 1 048 sources actives (employeurs directs par plateforme ATS + portails), avec l'état de chaque connecteur. Chaque offre est traçable à son origine.
5. Observatoire de l'emploi — /stats
Le tableau de bord analytique (kit stats v3 Groupe KA) : volumes par ville, catégorie, salaire, mode de travail… avec rapports PDF téléchargeables, y compris des rapports personnalisés.
6. Espace employeurs — /employeurs
Les employeurs québécois peuvent déposer leurs offres directement (POST /api/employeurs/offres) — modération manuelle avant publication.
7. Contact — /contact
Contact direct avec le Groupe KA — questions, retraits, partenariats, signalements.
8. Page ville — /ville/montreal
L'exemple type des pages villes : 8 176 offres à Montréal, filtrables sur place, avec métriques claires (salaire affiché, séniorité, mode de travail) issues de l'enrichissement des connecteurs.
9. Fiche d'offre — /emploi/{uid}
Une fiche complète (ici un poste chez 4Refuel, capté directement sur son ATS Dayforce) : description, salaire normalisé, exigences, localisation, JSON-LD JobPosting pour le SEO — et le bouton Postuler qui mène chez l'employeur, jamais ailleurs.
10. Favoris « Mon univers Ka » — /favoris
Les offres sauvegardées avec le cœur, synchronisées via KA ID (le SSO du Groupe KA) — le même compte retrouve ses favoris sur les 13 sites de l'écosystème.
📷 Captures précédentes (refonte du 2026-08-25, mobile + desktop)
Mobile
![]() Accueil — recherche d'offres |
![]() Offres à Montréal — métriques claires |
![]() Fiche d'offre — exigences, séniorité |
![]() Carte des offres géocodées |
![]() Observatoire de l'emploi |
![]() Nav v2 — panneau plein écran |
Desktop
![]() Accueil — design éditorial premium |
![]() Résultats par ville — Montréal |
![]() Fiche d'offre — lien direct vers l'ATS de l'employeur |
![]() Carte des offres |
![]() Répertoire des villes (pages SEO) |
![]() Statistiques — 22 900+ postes |
🗄️ Les captures d'époque sont conservées dans
docs/archive/.
Nouveautés front-end (2026-08-25)
- Refonte visuelle majeure — design éditorial premium sur tout le site.
- Affichage des offres repensé — métriques claires (salaire, exigences, séniorité) issues de l'enrichissement des 1 100+ connecteurs (phase 3).
- Vagues D et E de connecteurs ATS — +135 employeurs (JazzHR, Teamtailor, Zoho Recruit…).
- Nav mobile v2 — hamburger + panneau plein écran (standard KA 2026-08-25).
- Widget ka-agent v4 — cartes d'offres cliquables et choix en boutons.
Guide pas à pas (« Utiliser le site en 4 étapes », depuis /doc)
![]() Étape 1 — Arriver sur l'accueil |
![]() Étape 2 — Chercher et filtrer les offres |
![]() Étape 3 — Lire la fiche et postuler chez l'employeur |
![]() Étape 4 — Explorer par la carte (et plus) |
Fonctionnalités
- Recherche filtrée — texte, ville, catégorie (16 catégories : TI, Santé, Finance, Ingénierie…), région, langue, mode de travail (dont télétravail), type d'emploi, salaire minimum / « salaire affiché », tri, pagination.
- Connecteurs auto-découverts — toute sous-classe de
BaseConnectoravec unsource_idest enregistrée parpkgutil; brancher un nouvel employeur sur une plateforme ATS = ~10 lignes. Politesse : throttling par source, User-Agent identifiableJobKaBot/1.0, budgets de requêtes, cache des pages détail. - Diff engine anti-dérive — comparaison par
content_hashà chaque sync ; une offre absente 2 syncs passeactive=0(jamais de DELETE) ; si une source retourne ≤ 25 % de sa médiane historique, alerte et retraits suspendus. - Salaires normalisés, jamais inventés —
parse_salary()exige un signe monétaire ou une unité explicite, bornes de plausibilité, conversion $/h ↔ $/an, historique des changements (salary_log). - Géocodage sans invention — Nominatim + repli officiel Adresses Québec (MERN), cache persistant, validation par bounding box provinciale ; carte des offres (MapLibre, sans jeton) via
GET /api/jobs.geojson. - Déduplication inter-sources direct-prioritaire — union-find avec second signal concordant ; en cas de doublon, l'offre de la page carrière (badge « Offre directe ») devient la canonique, les copies portail sont masquées (
dup_of), jamais supprimées. - Quarantaine qualité — offres douteuses exclues des points d'accès publics (
jobka/quality.py), supervisables viaquarantined=1. - Dépôt direct employeurs —
/employeurs(POST /api/employeurs/offres), modération manuelle. - SEO programmatique — SSR léger (accueil, fiches JSON-LD JobPosting, pages statiques), robots.txt, sitemaps, pages
/villes+/ville/{slug}rendues en HTML. - Page /stats — tableau de bord analytique + rapports PDF Groupe-KA (kit kacharts/kapdf v3, rapports personnalisés) ; favoris « Mon univers Ka » (KA ID, cœur sur cartes et fiche, page
/favoris). - Conformité documentée —
docs/CONFORMITE.md(base d'accès par famille de sources, attribution, zéro donnée personnelle de candidat) + une fiche générée par connecteur dansdocs/connecteurs/(1 133 fiches). - Tests hors ligne — 74 tests pytest : fixtures HTTP enregistrées et rejouées, invariants (uid uniques, URLs absolues, salaires plausibles).
- Supervision par agents gardiens — les connecteurs sont surveillés en continu (gardien ka6) : chaque panne de source est diagnostiquée (panne externe vs bug), documentée dans le connecteur et commitée — un sync en échec ne purge jamais rien.
Connecteurs & sources
| Famille | Détail | Volume |
|---|---|---|
| Employeurs directs (ATS) | 1 104 connecteurs sur 23 plateformes : Workday (233 employeurs), SmartRecruiters (172), Greenhouse (131), Dayforce (128), Breezy (72), Workable (71), Lever (58), Ashby (41), BambooHR (37), JazzHR (31), Recruitee (30), ADP WFN (17), Zoho Recruit (17), SuccessFactors (11), Njoyn (11), Teamtailor (9), WP Job Manager (8), iCIMS (7), Taleo Business Edition (7), Taleo (5), UltiPro/UKG (4), Digital Recruiters (2), réseau Atlas Workland (1 connecteur ≈ 80 employeurs QC) + sites carrières maison | 21 243 offres directes de 1 132 employeurs (au 2026-08-28) |
| Sites carrières maison | pages carrières sans ATS standard (certaines via Scrapfly) | inclus ci-dessus |
| Portails publics | Guichet-Emplois, Jobillico, Espresso-Jobs — complément, jamais prioritaire sur l'offre directe | 1 959 offres |
| Dépôt direct | formulaire /employeurs, modération manuelle |
à la demande |
Registre descriptif : data/sources.json (1 108 entrées, dont 1 en modération) ; une fiche de conformité par connecteur dans docs/connecteurs/ (1 133 fiches, index : docs/connecteurs/INDEX.md, régénérables par scripts/gen_connector_docs.py).
Cadence de resync : horaire, jour et nuit — le watcher PM2 job-ka-sync (run.py watch 60) enchaîne sync + géocodage + déduplication ; le diff engine par content_hash gère le cycle de vie (retrait après 2 syncs d'absence, anti-dérive à ≤ 25 % de la médiane historique). Les connecteurs fragiles passent par une chaîne de fetch anti-bot résiliente (Oxylabs → Scrapfly → Bright Data).
Architecture
Sources (23 plateformes ATS + sites maison + 3 portails)
→ connecteurs auto-découverts (jobka/connectors/)
→ finalize() — normalisation commune (schema.py, normalize.py)
→ SQLite data/jobka.db — diff par content_hash, cycle de vie, anti-dérive (db.py)
→ géocodage (geocode.py) + déduplication (dedup.py) + quarantaine (quality.py)
→ API FastAPI (web.py) + frontend React/Vite servi en statique (frontend/dist)- Backend : Python + FastAPI (uvicorn) — API JSON, SSR SEO léger, stats, PDF (fpdf2), SSO/favoris KA ID.
- Base de données : SQLite (
data/jobka.db, non versionnée) — offres, historique salarial, cache de géocodage, journal des syncs. - Frontend : React 18 + Vite + TypeScript, carte MapLibre GL (sans jeton), design system Groupe KA ; build servi en statique par FastAPI.
- Anti-bot : chaîne résiliente Oxylabs → Scrapfly → Bright Data pour certaines pages carrières maison (
SCRAPFLY_API_KEY).
API — endpoints principaux
| Endpoint | Méthode | Rôle |
|---|---|---|
/api/jobs |
GET | recherche filtrée : texte, ville, catégorie, région, langue, mode de travail, type, salaire, tri, pagination |
/api/jobs/{uid} |
GET | fiche complète d'une offre (source, salaire normalisé, logo, lien de candidature direct) |
/api/jobs.geojson |
GET | offres géocodées pour la carte MapLibre |
/api/facets |
GET | facettes de filtres (villes, catégories, types, modes, régions, langues) |
/api/sources |
GET | registre des sources et état des connecteurs |
/api/employeurs/offres |
POST | dépôt direct d'offres par les employeurs (modération manuelle) |
/api/stats |
GET | agrégats publics (source des pastilles dynamiques ci-dessus) |
/api/stats/catalog · /api/stats/dashboard |
GET | catalogue de blocs + tableau de bord (kit stats v3 Groupe KA) |
/api/stats/report · /api/stats/report/custom |
GET/POST | rapports PDF Groupe-KA (5 modes + personnalisés) |
/api/favorites · /api/favorites/toggle |
GET/POST | favoris « Mon univers Ka » (KA ID) |
/api/sync |
POST | déclenchement de synchronisation (interne) |
/health |
GET | santé du service |
Données & conformité
- Provenance : API publiques des plateformes ATS (base légale documentée dans
docs/CONFORMITE.md), pages carrières publiques, portails publics ; zéro donnée personnelle de candidat — Job·Ka n'indexe que des offres. - Attribution : chaque offre conserve son URL originale ; la candidature se fait chez l'employeur (badge « Offre directe » sur les sources directes).
- Cadence : resync horaire jour et nuit (
run.py watch 60) ; retrait doux après 2 syncs d'absence ; anti-dérive à ≤ 25 % de la médiane historique. - Salaires : jamais inventés — signe monétaire ou unité explicite obligatoire, bornes de plausibilité, conversion $/h ↔ $/an documentée.
- Traçabilité : 1 133 fiches de conformité générées (
docs/connecteurs/), registredata/sources.jsonauditable (sources écartées documentées avec raisons).
Structure du repo
| Répertoire / fichier | Rôle |
|---|---|
jobka/ |
paquet Python : schéma JobPosting, normalisation, DB/diff, ingestion, dédup, géocodage, quarantaine qualité, web/API, stats, PDF, auth KA ID |
jobka/connectors/ |
base commune + 23 plateformes ATS + ~1 100 connecteurs (1 fichier = 1 employeur) + portails — 1 133 modules au total |
frontend/ |
React 18 + Vite + TS (carte MapLibre) — dist/ non versionné ; guide /doc dans frontend/public/doc/ |
data/ |
sources.json (registre descriptif, 1 108 entrées) + jobka.db (non versionnée) |
tests/ |
pytest : normalisation + rejeu hors ligne des fixtures connecteurs — 74 tests |
scripts/ |
check_headers.py (en-tête d'auteur obligatoire), gen_connector_docs.py (fiches connecteurs), probe_ats.py + éclaireur Serper (campagnes connecteurs) |
docs/ |
CONFORMITE.md, connecteurs/ (1 133 fiches + INDEX), deploiement.md, screenshots/ (visite guidée) |
run.py |
CLI : sync · watch · serve · geocode · record |
requirements.txt |
fastapi, uvicorn, requests, beautifulsoup4, fpdf2 |
Démarrage rapide
ssh M3U96a && cd ~/apps/job-ka
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt # au besoin
.venv/bin/python -m pytest # 74 tests hors ligne (fixtures rejouées)
.venv/bin/python run.py sync <source> # valider un connecteur précis
.venv/bin/python run.py sync # sync complet (toutes les sources)
.venv/bin/python run.py serve 8096 # API + frontend statique
cd frontend && npm install && npm run build # rebuild du frontend (tsc -b && vite build)Développement (remote-first)
⚠️ La source de vérité est le repo git sur le nœud M3U96a (~/apps/job-ka) — on n'édite jamais les copies laptop. Toute modification se fait sur le nœud via SSH : édition, tests, build frontend au besoin, redémarrage PM2, puis commit + push depuis le nœud.
- Remote
origin= spbgit (git perso, https://git.spboucher.ai) — sur M3U96a, l'origin est le chemin local/Users/simon-pierreboucher/srv/git/job-ka.git(bare repo). - On ne pousse que le code :
data/*.db,frontend/dist/et.envne sont jamais versionnés — le serveur maintient ses données lui-même.
cd ~/apps/job-ka
.venv/bin/python -m pytest # avant de pousser
cd frontend && npm run build && cd .. # si le frontend a changé
pm2 restart job-ka-web # après changement
git add <fichiers> && git commit -m "…" && git push origin mainVariables d'environnement
Noms seulement — aucun secret n'est versionné.
| Variable | Rôle |
|---|---|
SCRAPFLY_API_KEY |
anti-bot pour certaines pages carrières maison |
KA_SSO_SECRET · KA_HUB_URL |
SSO KA ID (hub groupe-ka.com) |
JOBKA_BASE_URL |
URL canonique du site (SEO, liens absolus) |
JOBKA_WORKDAY_DETAIL_LIMIT · JOBKA_SR_DETAIL_LIMIT · JOBKA_DAYFORCE_DETAIL_LIMIT … |
budgets de requêtes détail par plateforme ATS (JOBKA_<PLATEFORME>_DETAIL_LIMIT) |
JOBKA_GUICHET_PAGES · JOBKA_GUICHET_DAYS · JOBKA_ESPRESSO_PAGES · JOBKA_JOBILLICO_TRACK … |
réglages des portails — documentés dans docs/connecteurs/INDEX.md |
Déploiement
| Nœud | M3U96a (cluster MacLustr) — ~/apps/job-ka |
| Port | 8096 |
| Domaine | www.job-ka.com via tunnel ngrok |
| Processus PM2 | Commande réelle | Rôle |
|---|---|---|
job-ka-web |
.venv/bin/python run.py serve 8096 |
API FastAPI + frontend statique |
job-ka-sync |
.venv/bin/python run.py watch 60 |
resync horaire + géocodage + dédup, jour et nuit |
job-ka-ngrok |
ngrok http --url=www.job-ka.com 8096 |
tunnel vers www.job-ka.com |
Détails : docs/deploiement.md.
Documentation
- Guide utilisateur en ligne : www.job-ka.com/doc/ — à quoi sert le site, utilisation en 4 étapes, provenance des données, FAQ.
- Guide PDF téléchargeable : job-ka-documentation.pdf.
- Conformité & connecteurs :
docs/CONFORMITE.md+ une fiche par connecteur dansdocs/connecteurs/(1 133 fiches, index :docs/connecteurs/INDEX.md).
Historique
| Date | Jalon |
|---|---|
| 2026-08-17 | fondation Job·Ka (socle backend, 5 connecteurs pilotes, frontend, tests) puis création massive : 135 connecteurs sur 9 plateformes ATS + intégration écosystème Groupe KA |
| 2026-08-19 | phase 2-3 qualité : salaires structurés, langue fr/en, quarantaine, régions MAMH ; nouvelles familles Taleo Business Edition, WP Job Manager (Santé Québec), réseau Atlas Workland (~80 employeurs, 1 connecteur) ; registre 244 sources + conformité |
| 2026-08-22 | vague B : +110 sources (dont la famille Dayforce, 26 connecteurs) ; SEO SSR (fiches JobPosting, sitemaps) ; chaîne de fetch anti-bot résiliente ; page Publier |
| 2026-08-23 | vague C : +620 connecteurs employeurs directs (350 → 968) ; SEO villes programmatique ; stats v3 (rapports PDF personnalisés) ; favoris « Mon univers Ka » |
| 2026-08-24 | page /doc (guide + captures + PDF), README v3 — état : 969 employeurs directs, 21 plateformes ATS, 21 492 offres actives |
| 2026-08-25 | refonte « éditorial premium » + vagues D-E : +135 employeurs (nouvelles familles JazzHR, Teamtailor, Zoho Recruit) ; nav mobile v2 ; widget ka-agent v4 |
| 2026-08-28 | README v4 + visite guidée en 10 captures (docs/screenshots/) — état : 1 104 connecteurs directs sur 23 plateformes ATS, 22 634 offres actives de 1 733 employeurs |
Écosystème Groupe KA
| Site | Univers |
|---|---|
| groupe-ka.com | portail |
| lou-ka.com | logements à louer |
| immo-ka.com | propriétés à vendre |
| vrai-prix.com | estimation immobilière |
| auto-ka.com | véhicules |
| fabri-ka.com | produits québécois |
| food-ka.com | épicerie / alimentation |
| resto-ka.com | restaurants |
| sorti-ka.com | sorties et événements |
| job-ka.com | emplois |
| crea-ka.com | créateurs |
| trouve-ka.com | petites annonces |
| api-ka.com | API de données |
Contact
Simon-Pierre Boucher — fondateur, Groupe KA 📧 contact@spboucher.ai
© Groupe KA — Simon-Pierre Boucher · contact@spboucher.ai
Ce dépôt vit sur spbgit (git perso — https://git.spboucher.ai).
















