docs: README v3 — chiffres live vérifiés, pastilles dynamiques, sections complètes
1 changed file +109 −44
modified
README.md
+109 −44
@@ -25,17 +25,46 @@ Créé : 2026-08-17 Modifié : 2026-08-24 | ||
| 25 | 25 |  |
| 26 | 26 |  |
| 27 | 27 |  |
| 28 | + | |
| 29 | +[](https://www.job-ka.com/api/stats) | |
| 30 | +[](https://www.job-ka.com/api/stats) | |
| 31 | +[](https://www.job-ka.com/api/stats) | |
| 32 | +[](https://www.job-ka.com/api/stats) | |
| 33 | +[](https://www.job-ka.com/api/stats) | |
| 34 | +[](https://www.job-ka.com/api/stats) | |
| 35 | +[](https://www.job-ka.com/api/stats) | |
| 36 | + | |
| 28 | 37 |  |
| 38 | + | |
| 29 | 39 |  |
| 40 | + | |
| 30 | 41 |  |
| 31 | 42 |  |
| 43 | + | |
| 44 | + | |
| 32 | 45 |  |
| 46 | + | |
| 33 | 47 | |
| 34 | 48 | </div> |
| 35 | 49 | |
| 36 | −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 : **968 connecteurs employeurs directs** sur **17 plateformes ATS** (Workday, Lever, Greenhouse, SmartRecruiters, BambooHR, Breezy, Recruitee, Ashby, Workable, Taleo, Njoyn, UltiPro, iCIMS, SuccessFactors, ADP WFN, Digital Recruiters, Workland), complétés par **3 portails publics** (Guichet-Emplois, Jobillico, Espresso-Jobs) — l'offre directe gagne toujours. | |
| 50 | +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 : **969 connecteurs employeurs directs** sur **21 plateformes ATS** (Workday, SmartRecruiters, Dayforce, Workable, Workland/réseau Atlas, SuccessFactors, Njoyn, Greenhouse, WP Job Manager, Lever, Breezy, Ashby, Recruitee, BambooHR, Taleo Business Edition, Taleo, Digital Recruiters, iCIMS, UltiPro/UKG, ADP WFN + sites carrières maison), complétés par **3 portails publics** (Guichet-Emplois, Jobillico, Espresso-Jobs) — l'offre directe gagne toujours. | |
| 51 | + | |
| 52 | +Résultat en base (au 2026-08-24) : **21 492 offres actives** de **1 653 employeurs** (963 sources), dont **19 856 offres directes** et **6 856 avec salaire affiché** (moyenne 62 283 $/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. | |
| 37 | 53 | |
| 38 | −Résultat en base : plus de **21 000 offres actives** de plus de **1 600 employeurs** (≈960 sources), dont ~**19 800 offres directes** et près de **6 900 avec salaire affiché** — 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. | |
| 54 | +## Chiffres clés (live sur [/api/stats](https://www.job-ka.com/api/stats), vérifiés au 2026-08-24) | |
| 55 | + | |
| 56 | +| Métrique | Valeur | | |
| 57 | +|---|---| | |
| 58 | +| Offres actives | **21 492** (98 doublons inter-sources masqués, 227 en quarantaine qualité) | | |
| 59 | +| Offres directes (pages carrières / ATS) | **19 856** — de 1 048 employeurs directs | | |
| 60 | +| Offres portails (complément) | 1 863 | | |
| 61 | +| Employeurs | **1 653** | | |
| 62 | +| Sources actives | **963** (registre : 973 entrées ; 969 employeurs directs connectés via 21 plateformes ATS + 3 portails + dépôt direct) | | |
| 63 | +| Avec salaire affiché | **6 856** — salaire moyen affiché ≈ **62 283 $/an** | | |
| 64 | +| Télétravail | **1 013** | | |
| 65 | +| Offres géocodées (carte) | **16 303** | | |
| 66 | +| Top villes | Montréal 7 645 · Québec 3 637 · Dorval 734 · Laval 733 | | |
| 67 | +| Top catégories | TI 2 699 · Santé 2 302 · Service à la clientèle 1 380 · Ventes 1 297 | | |
| 39 | 68 | |
| 40 | 69 | ## Visite guidée |
| 41 | 70 | |
@@ -61,75 +90,99 @@ Résultat en base : plus de **21 000 offres actives** de plus de **1 600 employe | ||
| 61 | 90 | |
| 62 | 91 | ## Fonctionnalités |
| 63 | 92 | |
| 64 | −- **Recherche filtrée** — texte, ville, catégorie (16 catégories : TI, Santé, Finance, Ingénierie…), mode de travail (dont télétravail), type d'emploi, **salaire minimum / « salaire affiché »**, tri, pagination. | |
| 93 | +- **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. | |
| 65 | 94 | - **Connecteurs auto-découverts** — toute sous-classe de `BaseConnector` avec un `source_id` est enregistrée par `pkgutil` ; brancher un nouvel employeur sur une plateforme ATS = **~10 lignes**. Politesse : throttling par source, User-Agent identifiable `JobKaBot/1.0`, budgets de requêtes, cache des pages détail. |
| 66 | 95 | - **Diff engine anti-dérive** — comparaison par `content_hash` à chaque sync ; une offre absente 2 syncs passe `active=0` (jamais de DELETE) ; si une source retourne ≤ 25 % de sa médiane historique, alerte et retraits suspendus. |
| 67 | 96 | - **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`). |
| 68 | 97 | - **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`. |
| 69 | 98 | - **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. |
| 99 | +- **Quarantaine qualité** — offres douteuses exclues des points d'accès publics (`jobka/quality.py`), supervisables via `quarantined=1`. | |
| 70 | 100 | - **Dépôt direct employeurs** — `/employeurs` (`POST /api/employeurs/offres`), modération manuelle. |
| 71 | −- **Page /stats** — tableau de bord analytique + rapports PDF Groupe-KA (kit kacharts/kapdf) ; **favoris « Mon univers Ka »** (KA ID, cœur sur cartes et fiche, page `/favoris`). | |
| 72 | −- **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 dans `docs/connecteurs/`. | |
| 73 | −- **Tests hors ligne** — fixtures HTTP enregistrées et rejouées (pytest), invariants (uid uniques, URLs absolues, salaires plausibles). | |
| 101 | +- **SEO programmatique** — SSR léger (accueil, fiches JSON-LD JobPosting, pages statiques), robots.txt, sitemaps, pages `/villes` + `/ville/{slug}` rendues en HTML. | |
| 102 | +- **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`). | |
| 103 | +- **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 dans `docs/connecteurs/` (995 fiches). | |
| 104 | +- **Tests hors ligne** — **74 tests pytest** : fixtures HTTP enregistrées et rejouées, invariants (uid uniques, URLs absolues, salaires plausibles). | |
| 74 | 105 | |
| 75 | 106 | ## Connecteurs & sources |
| 76 | 107 | |
| 77 | 108 | | Famille | Détail | Volume | |
| 78 | 109 | |---|---|---| |
| 79 | −| **Employeurs directs (ATS)** | 968 connecteurs sur 17 plateformes : Workday, Lever, Greenhouse, SmartRecruiters, BambooHR, Breezy, Recruitee, Ashby, Workable, Taleo, Njoyn, UltiPro, iCIMS, SuccessFactors, ADP WFN, Digital Recruiters, Workland | ~19 800 offres directes | | |
| 110 | +| **Employeurs directs (ATS)** | **969 connecteurs sur 21 plateformes** : Workday (206 employeurs), SmartRecruiters (158), Greenhouse (129), Dayforce (122), Breezy (72), Workable (70), Lever (57), Ashby (40), BambooHR (34), Recruitee (30), SuccessFactors (9), WP Job Manager (8), Njoyn (6), Taleo Business Edition (6), iCIMS (6), ADP WFN (5), Taleo (4), UltiPro/UKG (3), Digital Recruiters (2), réseau Atlas Workland (1 connecteur ≈ 80 employeurs QC), sites maison | **19 856 offres directes** (au 2026-08-24) | | |
| 80 | 111 | | **Sites carrières maison** | pages carrières sans ATS standard (certaines via Scrapfly) | inclus ci-dessus | |
| 81 | −| **Portails publics** | Guichet-Emplois, Jobillico, Espresso-Jobs — complément, jamais prioritaire sur l'offre directe | le reste des ~21 000 offres | | |
| 112 | +| **Portails publics** | Guichet-Emplois, Jobillico, Espresso-Jobs — complément, jamais prioritaire sur l'offre directe | 1 863 offres | | |
| 82 | 113 | | **Dépôt direct** | formulaire `/employeurs`, modération manuelle | à la demande | |
| 83 | 114 | |
| 84 | −Registre descriptif : `data/sources.json` (~970 entrées) ; une fiche de conformité par connecteur dans `docs/connecteurs/` (`scripts/gen_connector_docs.py`). | |
| 115 | +Registre descriptif : `data/sources.json` (**973 entrées**, dont 1 en modération) ; une fiche de conformité par connecteur dans `docs/connecteurs/` (995 fiches, index : `docs/connecteurs/INDEX.md`, régénérables par `scripts/gen_connector_docs.py`). | |
| 85 | 116 | |
| 86 | −**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). | |
| 117 | +**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). | |
| 87 | 118 | |
| 88 | 119 | ## Architecture |
| 89 | 120 | |
| 90 | 121 | ``` |
| 91 | −Sources (17 plateformes ATS + sites maison + 3 portails) | |
| 122 | +Sources (21 plateformes ATS + sites maison + 3 portails) | |
| 92 | 123 | → connecteurs auto-découverts (jobka/connectors/) |
| 93 | 124 | → finalize() — normalisation commune (schema.py, normalize.py) |
| 94 | 125 | → SQLite data/jobka.db — diff par content_hash, cycle de vie, anti-dérive (db.py) |
| 95 | − → géocodage (geocode.py) + déduplication (dedup.py) | |
| 126 | + → géocodage (geocode.py) + déduplication (dedup.py) + quarantaine (quality.py) | |
| 96 | 127 | → API FastAPI (web.py) + frontend React/Vite servi en statique (frontend/dist) |
| 97 | 128 | ``` |
| 98 | 129 | |
| 99 | −- **Backend** : Python + **FastAPI** (uvicorn) — API JSON, stats, PDF, SSO/favoris KA ID. | |
| 130 | +- **Backend** : Python + **FastAPI** (uvicorn) — API JSON, SSR SEO léger, stats, PDF (fpdf2), SSO/favoris KA ID. | |
| 100 | 131 | - **Base de données** : **SQLite** (`data/jobka.db`, non versionnée) — offres, historique salarial, cache de géocodage, journal des syncs. |
| 101 | 132 | - **Frontend** : **React 18 + Vite + TypeScript**, carte **MapLibre GL** (sans jeton), design system Groupe KA ; build servi en statique par FastAPI. |
| 102 | −- **Anti-bot** : Scrapfly pour certaines pages carrières maison (`SCRAPFLY_API_KEY`). | |
| 133 | +- **Anti-bot** : chaîne résiliente Oxylabs → Scrapfly → Bright Data pour certaines pages carrières maison (`SCRAPFLY_API_KEY`). | |
| 103 | 134 | |
| 104 | 135 | ## API — endpoints principaux |
| 105 | 136 | |
| 106 | −| Endpoint | Rôle | | |
| 107 | −|---|---| | |
| 108 | −| `GET /api/jobs` | recherche filtrée : texte, ville, catégorie, mode de travail, type, salaire, tri, pagination | | |
| 109 | −| `GET /api/jobs/{uid}` | fiche complète d'une offre (source, salaire normalisé, lien de candidature direct) | | |
| 110 | −| `GET /api/jobs.geojson` | offres géocodées pour la carte MapLibre | | |
| 111 | −| `GET /api/facets` | facettes de filtres (villes, catégories, types, modes) | | |
| 112 | −| `GET /api/sources` | registre des sources et état des connecteurs | | |
| 113 | −| `POST /api/employeurs/offres` | dépôt direct d'offres par les employeurs (modération manuelle) | | |
| 114 | −| `GET /api/stats` · `/api/stats/catalog` · `/api/stats/dashboard` · `/api/stats/report(/custom)` | tableau de bord + rapports PDF Groupe-KA | | |
| 115 | −| `GET /api/favorites` · `POST /api/favorites/toggle` | favoris « Mon univers Ka » (KA ID) | | |
| 116 | −| `POST /api/sync` | déclenchement de synchronisation (interne) | | |
| 117 | −| `GET /health` | santé du service | | |
| 137 | +| Endpoint | Méthode | Rôle | | |
| 138 | +|---|---|---| | |
| 139 | +| `/api/jobs` | GET | recherche filtrée : texte, ville, catégorie, région, langue, mode de travail, type, salaire, tri, pagination | | |
| 140 | +| `/api/jobs/{uid}` | GET | fiche complète d'une offre (source, salaire normalisé, logo, lien de candidature direct) | | |
| 141 | +| `/api/jobs.geojson` | GET | offres géocodées pour la carte MapLibre | | |
| 142 | +| `/api/facets` | GET | facettes de filtres (villes, catégories, types, modes, régions, langues) | | |
| 143 | +| `/api/sources` | GET | registre des sources et état des connecteurs | | |
| 144 | +| `/api/employeurs/offres` | POST | dépôt direct d'offres par les employeurs (modération manuelle) | | |
| 145 | +| `/api/stats` | GET | agrégats publics (source des pastilles dynamiques ci-dessus) | | |
| 146 | +| `/api/stats/catalog` · `/api/stats/dashboard` | GET | catalogue de blocs + tableau de bord (kit stats v3 Groupe KA) | | |
| 147 | +| `/api/stats/report` · `/api/stats/report/custom` | GET/POST | rapports PDF Groupe-KA (5 modes + personnalisés) | | |
| 148 | +| `/api/favorites` · `/api/favorites/toggle` | GET/POST | favoris « Mon univers Ka » (KA ID) | | |
| 149 | +| `/api/sync` | POST | déclenchement de synchronisation (interne) | | |
| 150 | +| `/health` | GET | santé du service | | |
| 151 | + | |
| 152 | +## Données & conformité | |
| 153 | + | |
| 154 | +- **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. | |
| 155 | +- **Attribution** : chaque offre conserve son URL originale ; la candidature se fait **chez l'employeur** (badge « Offre directe » sur les sources directes). | |
| 156 | +- **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. | |
| 157 | +- **Salaires** : jamais inventés — signe monétaire ou unité explicite obligatoire, bornes de plausibilité, conversion $/h ↔ $/an documentée. | |
| 158 | +- **Traçabilité** : 995 fiches de conformité générées (`docs/connecteurs/`), registre `data/sources.json` auditable (sources écartées documentées avec raisons). | |
| 118 | 159 | |
| 119 | 160 | ## Structure du repo |
| 120 | 161 | |
| 121 | 162 | | Répertoire / fichier | Rôle | |
| 122 | 163 | |---|---| |
| 123 | −| `jobka/` | paquet Python : schéma `JobPosting`, normalisation, DB/diff, ingestion, dédup, géocodage, web/API, stats, PDF, auth KA ID | | |
| 124 | −| `jobka/connectors/` | base commune + 17 plateformes ATS + ~970 connecteurs (1 fichier = 1 employeur) + portails | | |
| 164 | +| `jobka/` | paquet Python : schéma `JobPosting`, normalisation, DB/diff, ingestion, dédup, géocodage, quarantaine qualité, web/API, stats, PDF, auth KA ID | | |
| 165 | +| `jobka/connectors/` | base commune + 21 plateformes ATS + ~970 connecteurs (1 fichier = 1 employeur) + portails — 995 modules au total | | |
| 125 | 166 | | `frontend/` | React 18 + Vite + TS (carte MapLibre) — `dist/` non versionné ; guide `/doc` dans `frontend/public/doc/` | |
| 126 | −| `data/` | `sources.json` (registre descriptif, ~970 entrées) + `jobka.db` (non versionnée) | | |
| 127 | −| `tests/` | pytest : normalisation + rejeu hors ligne des fixtures connecteurs | | |
| 128 | −| `scripts/` | `check_headers.py` (en-tête d'auteur obligatoire), `gen_connector_docs.py` (fiches connecteurs) | | |
| 129 | −| `docs/` | `CONFORMITE.md`, `connecteurs/`, `deploiement.md`, captures d'écran | | |
| 167 | +| `data/` | `sources.json` (registre descriptif, 973 entrées) + `jobka.db` (non versionnée) | | |
| 168 | +| `tests/` | pytest : normalisation + rejeu hors ligne des fixtures connecteurs — 74 tests | | |
| 169 | +| `scripts/` | `check_headers.py` (en-tête d'auteur obligatoire), `gen_connector_docs.py` (fiches connecteurs), `probe_ats.py` + éclaireur Serper (campagnes connecteurs) | | |
| 170 | +| `docs/` | `CONFORMITE.md`, `connecteurs/` (995 fiches + INDEX), `deploiement.md`, captures d'écran | | |
| 130 | 171 | | `run.py` | CLI : `sync` · `watch` · `serve` · `geocode` · `record` | |
| 131 | 172 | | `requirements.txt` | fastapi, uvicorn, requests, beautifulsoup4, fpdf2 | |
| 132 | 173 | |
| 174 | +## Démarrage rapide | |
| 175 | + | |
| 176 | +```bash | |
| 177 | +ssh M3U96a && cd ~/apps/job-ka | |
| 178 | +python3 -m venv .venv && .venv/bin/pip install -r requirements.txt # au besoin | |
| 179 | +.venv/bin/python -m pytest # 74 tests hors ligne (fixtures rejouées) | |
| 180 | +.venv/bin/python run.py sync <source> # valider un connecteur précis | |
| 181 | +.venv/bin/python run.py sync # sync complet (toutes les sources) | |
| 182 | +.venv/bin/python run.py serve 8096 # API + frontend statique | |
| 183 | +cd frontend && npm install && npm run build # rebuild du frontend (tsc -b && vite build) | |
| 184 | +``` | |
| 185 | + | |
| 133 | 186 | ## Développement (remote-first) |
| 134 | 187 | |
| 135 | 188 | ⚠️ **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**. |
@@ -138,22 +191,24 @@ Sources (17 plateformes ATS + sites maison + 3 portails) | ||
| 138 | 191 | - On ne pousse **que le code** : `data/*.db`, `frontend/dist/` et `.env` ne sont jamais versionnés — le serveur maintient ses données lui-même. |
| 139 | 192 | |
| 140 | 193 | ```bash |
| 141 | −ssh M3U96a | |
| 142 | 194 | cd ~/apps/job-ka |
| 143 | −.venv/bin/python -m pytest # tests hors ligne | |
| 144 | −.venv/bin/python run.py sync <source> # valider un connecteur | |
| 195 | +.venv/bin/python -m pytest # avant de pousser | |
| 145 | 196 | cd frontend && npm run build && cd .. # si le frontend a changé |
| 146 | 197 | pm2 restart job-ka-web # après changement |
| 147 | 198 | git add <fichiers> && git commit -m "…" && git push origin main |
| 148 | 199 | ``` |
| 149 | 200 | |
| 150 | −### Configuration notable (sans secrets) | |
| 201 | +## Variables d'environnement | |
| 202 | + | |
| 203 | +Noms seulement — **aucun secret n'est versionné**. | |
| 151 | 204 | |
| 152 | 205 | | Variable | Rôle | |
| 153 | 206 | |---|---| |
| 154 | 207 | | `SCRAPFLY_API_KEY` | anti-bot pour certaines pages carrières maison | |
| 155 | −| `JOBKA_WORKDAY_DETAIL_LIMIT` · `JOBKA_SR_DETAIL_LIMIT` | budgets de requêtes détail (Workday, SmartRecruiters) | | |
| 156 | −| autres `JOBKA_<PLATEFORME>_*` | budgets par plateforme ATS — documentés dans `docs/connecteurs/INDEX.md` | | |
| 208 | +| `KA_SSO_SECRET` · `KA_HUB_URL` | SSO KA ID (hub groupe-ka.com) | | |
| 209 | +| `JOBKA_BASE_URL` | URL canonique du site (SEO, liens absolus) | | |
| 210 | +| `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`) | | |
| 211 | +| `JOBKA_GUICHET_PAGES` · `JOBKA_GUICHET_DAYS` · `JOBKA_ESPRESSO_PAGES` · `JOBKA_JOBILLICO_TRACK` … | réglages des portails — documentés dans `docs/connecteurs/INDEX.md` | | |
| 157 | 212 | |
| 158 | 213 | ## Déploiement |
| 159 | 214 | |
@@ -163,11 +218,11 @@ git add <fichiers> && git commit -m "…" && git push origin main | ||
| 163 | 218 | | **Port** | **8096** | |
| 164 | 219 | | **Domaine** | [www.job-ka.com](https://www.job-ka.com) via tunnel ngrok | |
| 165 | 220 | |
| 166 | −| Processus PM2 | Rôle | | |
| 167 | −|---|---| | |
| 168 | −| `job-ka-web` | `run.py serve 8096` — API FastAPI + frontend statique | | |
| 169 | −| `job-ka-sync` | `run.py watch 60` — resync horaire + géocodage + dédup, jour et nuit | | |
| 170 | −| `job-ka-ngrok` | tunnel ngrok vers www.job-ka.com | | |
| 221 | +| Processus PM2 | Commande réelle | Rôle | | |
| 222 | +|---|---|---| | |
| 223 | +| `job-ka-web` | `.venv/bin/python run.py serve 8096` | API FastAPI + frontend statique | | |
| 224 | +| `job-ka-sync` | `.venv/bin/python run.py watch 60` | resync horaire + géocodage + dédup, jour et nuit | | |
| 225 | +| `job-ka-ngrok` | `ngrok http --url=www.job-ka.com 8096` | tunnel vers www.job-ka.com | | |
| 171 | 226 | |
| 172 | 227 | Détails : `docs/deploiement.md`. |
| 173 | 228 | |
@@ -175,7 +230,17 @@ Détails : `docs/deploiement.md`. | ||
| 175 | 230 | |
| 176 | 231 | - **Guide utilisateur en ligne** : [www.job-ka.com/doc/](https://www.job-ka.com/doc/) — à quoi sert le site, utilisation en 4 étapes, provenance des données, FAQ. |
| 177 | 232 | - **Guide PDF téléchargeable** : [job-ka-documentation.pdf](https://www.job-ka.com/doc/job-ka-documentation.pdf). |
| 178 | −- **Conformité & connecteurs** : `docs/CONFORMITE.md` + une fiche par connecteur dans `docs/connecteurs/` (index : `docs/connecteurs/INDEX.md`). | |
| 233 | +- **Conformité & connecteurs** : `docs/CONFORMITE.md` + une fiche par connecteur dans `docs/connecteurs/` (995 fiches, index : `docs/connecteurs/INDEX.md`). | |
| 234 | + | |
| 235 | +## Historique | |
| 236 | + | |
| 237 | +| Date | Jalon | | |
| 238 | +|---|---| | |
| 239 | +| 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 | | |
| 240 | +| 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é | | |
| 241 | +| 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 | | |
| 242 | +| 2026-08-23 | **vague C : +620 connecteurs employeurs directs (350 → 968)** ; SEO villes programmatique ; stats v3 (rapports PDF personnalisés) ; favoris « Mon univers Ka » | | |
| 243 | +| 2026-08-24 | page `/doc` (guide + captures + PDF), README v3 — état : 969 employeurs directs, 21 plateformes ATS, 21 492 offres actives | | |
| 179 | 244 | |
| 180 | 245 | ## Écosystème Groupe KA |
| 181 | 246 | |
| 182 | 247 | |