[ka6] fix connecteur strathmore: frontal ADP intermittent PAR CID (7e cas, garde-fou retry borné répliqué) — stale causé par le 404 nocturne du 30/10 23:57 (épisode multi-tenants 23:45→04:42) suivi d'un nouveau 404 isolé à 09:30 ; sonde live 3/6 essais 200 totalNumber=10 + 3 « default backend - 404 » de 21 octets = intermittence, tenant vivant ; garde-fou _get_json (30 essais, pause 2 s, timeout 15 s) répliqué de bento_sushi/cookit/mitsubishi_hc_capital/niobec/osgoode_properties/uv_assurance, complémentaire du repli « détail seulement » existant ; sync isolé vert found=9 (= médiane 9.0) en 5,4 s, 108 tests pytest verts, fiches strathmore.md/ats-adp.md/INDEX.md régénérées, pm2 restart job-ka-sync OK, site local 200, www.job-ka.com 200
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
4 changed files +104 −50
modified
docs/connecteurs/INDEX.md
+11 −11
@@ -5,16 +5,16 @@ Auteur : Simon-Pierre Boucher | |||||
| 5 | Contact : contact@spboucher.ai | 5 | Contact : contact@spboucher.ai | ||
| 6 | Fichier : docs/connecteurs/INDEX.md | 6 | Fichier : docs/connecteurs/INDEX.md | ||
| 7 | Rôle : Index généré de la documentation des connecteurs (ATS, employeurs, portails, dépôt) | 7 | Rôle : Index généré de la documentation des connecteurs (ATS, employeurs, portails, dépôt) | ||
| 8 | −Généré : 2026-10-31 10:38 EDT par scripts/gen_connector_docs.py — NE PAS ÉDITER, | 8 | +Généré : 2026-10-31 11:33 EDT par scripts/gen_connector_docs.py — NE PAS ÉDITER, | ||
| 9 | relancer le script pour régénérer. | 9 | relancer le script pour régénérer. | ||
| 10 | ============================================================================= | 10 | ============================================================================= | ||
| 11 | --> | 11 | --> | ||
| 12 | 12 | ||||
| 13 | # Job·Ka — Connecteurs (index) | 13 | # Job·Ka — Connecteurs (index) | ||
| 14 | 14 | ||||
| 15 | −> Index généré le 2026-10-31 10:38 EDT par `scripts/gen_connector_docs.py` (rejouable). Croise `data/sources.json`, l'introspection de `jobka/connectors/*.py` et la base live `data/jobka.db`. | 15 | +> Index généré le 2026-10-31 11:33 EDT par `scripts/gen_connector_docs.py` (rejouable). Croise `data/sources.json`, l'introspection de `jobka/connectors/*.py` et la base live `data/jobka.db`. | ||
| 16 | 16 | ||||
| 17 | −**1103 employeurs directs** connectés via **27 plateformes ATS** + **3 portails agrégateurs** + le canal de **dépôt direct** — **25234 offres actives** (22726 directes, 2508 portails ; 107 masquées comme doublons inter-sources, soit 25127 visibles). 1135 fiches. | 17 | +**1103 employeurs directs** connectés via **27 plateformes ATS** + **3 portails agrégateurs** + le canal de **dépôt direct** — **25246 offres actives** (22725 directes, 2521 portails ; 108 masquées comme doublons inter-sources, soit 25138 visibles). 1135 fiches. | ||
| 18 | 18 | ||||
| 19 | Conformité : voir [`docs/CONFORMITE.md`](../CONFORMITE.md). Chaque offre conserve son URL originale ; la candidature se fait chez l'employeur (badge « Offre directe » sur les sources directes). | 19 | Conformité : voir [`docs/CONFORMITE.md`](../CONFORMITE.md). Chaque offre conserve son URL originale ; la candidature se fait chez l'employeur (badge « Offre directe » sur les sources directes). | ||
| 20 | 20 | ||||
@@ -22,13 +22,13 @@ Conformité : voir [`docs/CONFORMITE.md`](../CONFORMITE.md). Chaque offre conser | |||||
| 22 | 22 | ||||
| 23 | | Plateforme | Employeurs | Actives | Salaire | GPS | | 23 | | Plateforme | Employeurs | Actives | Salaire | GPS | | ||
| 24 | |---|---|---|---|---| | 24 | |---|---|---|---|---| | ||
| 25 | −| [`workday`](ats-workday.md) | 232 | 7339 | 47 % | 88 % | | 25 | +| [`workday`](ats-workday.md) | 232 | 7340 | 47 % | 88 % | | ||
| 26 | | [`smartrecruiters`](ats-smartrecruiters.md) | 171 | 2894 | 16 % | 99 % | | 26 | | [`smartrecruiters`](ats-smartrecruiters.md) | 171 | 2894 | 16 % | 99 % | | ||
| 27 | | [`workable`](ats-workable.md) | 71 | 1994 | 17 % | 100 % | | 27 | | [`workable`](ats-workable.md) | 71 | 1994 | 17 % | 100 % | | ||
| 28 | | [`dayforce`](ats-dayforce.md) | 129 | 1897 | 10 % | 100 % | | 28 | | [`dayforce`](ats-dayforce.md) | 129 | 1897 | 10 % | 100 % | | ||
| 29 | | [`successfactors`](ats-successfactors.md) | 12 | 1639 | 19 % | 99 % | | 29 | | [`successfactors`](ats-successfactors.md) | 12 | 1639 | 19 % | 99 % | | ||
| 30 | | [`njoyn`](ats-njoyn.md) | 11 | 1265 | 69 % | 87 % | | 30 | | [`njoyn`](ats-njoyn.md) | 11 | 1265 | 69 % | 87 % | | ||
| 31 | −| [`workland`](ats-workland.md) | 1 | 1109 | 37 % | 100 % | | 31 | +| [`workland`](ats-workland.md) | 1 | 1107 | 37 % | 100 % | | ||
| 32 | | [`wpjobmanager`](ats-wpjobmanager.md) | 8 | 805 | 6 % | 100 % | | 32 | | [`wpjobmanager`](ats-wpjobmanager.md) | 8 | 805 | 6 % | 100 % | | ||
| 33 | | [`greenhouse`](ats-greenhouse.md) | 132 | 792 | 19 % | 100 % | | 33 | | [`greenhouse`](ats-greenhouse.md) | 132 | 792 | 19 % | 100 % | | ||
| 34 | | [`lever`](ats-lever.md) | 58 | 622 | 20 % | 95 % | | 34 | | [`lever`](ats-lever.md) | 58 | 622 | 20 % | 95 % | | ||
@@ -54,8 +54,8 @@ Conformité : voir [`docs/CONFORMITE.md`](../CONFORMITE.md). Chaque offre conser | |||||
| 54 | 54 | ||||
| 55 | | Source | Actives | Salaire | Dernier sync | | 55 | | Source | Actives | Salaire | Dernier sync | | ||
| 56 | |---|---|---|---| | 56 | |---|---|---|---| | ||
| 57 | −| [Espresso-Jobs](espresso_jobs.md) | 157 | 22 % | 2026-10-31 08:49 | | 57 | +| [Espresso-Jobs](espresso_jobs.md) | 157 | 22 % | 2026-10-31 11:12 | | ||
| 58 | −| [Guichet-Emplois (Canada)](guichet_emplois.md) | 519 | 100 % | 2026-10-31 09:01 | | 58 | +| [Guichet-Emplois (Canada)](guichet_emplois.md) | 532 | 100 % | 2026-10-31 11:23 | | ||
| 59 | | [Jobillico](jobillico.md) | 1832 | 35 % | 2026-10-31 09:08 | | 59 | | [Jobillico](jobillico.md) | 1832 | 35 % | 2026-10-31 09:08 | | ||
| 60 | | [Dépôt direct employeurs](depot-direct.md) | 0 (0 en modération) | — | au fil de l'eau | | 60 | | [Dépôt direct employeurs](depot-direct.md) | 0 (0 en modération) | — | au fil de l'eau | | ||
| 61 | 61 | ||||
@@ -63,8 +63,8 @@ Conformité : voir [`docs/CONFORMITE.md`](../CONFORMITE.md). Chaque offre conser | |||||
| 63 | 63 | ||||
| 64 | | Employeur | ATS | Actives | Salaire | GPS | Dernier sync OK | | 64 | | Employeur | ATS | Actives | Salaire | GPS | Dernier sync OK | | ||
| 65 | |---|---|---|---|---|---| | 65 | |---|---|---|---|---|---| | ||
| 66 | −| [Réseau Atlas Workland (~80 employeurs QC : CSS, cégeps, Santé Québec, STQ, UQTR…)](atlas_workland.md) | [`workland`](ats-workland.md) | 1109 | 37 % | 100 % | ✅ | | 66 | +| [Réseau Atlas Workland (~80 employeurs QC : CSS, cégeps, Santé Québec, STQ, UQTR…)](atlas_workland.md) | [`workland`](ats-workland.md) | 1107 | 37 % | 100 % | ✅ | | ||
| 67 | −| [Couche-Tard / Circle K](circlek.md) | [`workday`](ats-workday.md) | 983 | 70 % | 67 % | ✅ | | 67 | +| [Couche-Tard / Circle K](circlek.md) | [`workday`](ats-workday.md) | 984 | 70 % | 67 % | ✅ | | ||
| 68 | | [Solution SFT](solution_sft.md) | [`workable`](ats-workable.md) | 959 | 23 % | 100 % | ✅ | | 68 | | [Solution SFT](solution_sft.md) | [`workable`](ats-workable.md) | 959 | 23 % | 100 % | ✅ | | ||
| 69 | | [Bombardier](bombardier.md) | [`successfactors`](ats-successfactors.md) | 899 | 1 % | 100 % | ✅ | | 69 | | [Bombardier](bombardier.md) | [`successfactors`](ats-successfactors.md) | 899 | 1 % | 100 % | ✅ | | ||
| 70 | | [Walmart Canada](walmart.md) | [`workday`](ats-workday.md) | 877 | 98 % | 90 % | ✅ | | 70 | | [Walmart Canada](walmart.md) | [`workday`](ats-workday.md) | 877 | 98 % | 90 % | ✅ | | ||
@@ -472,7 +472,7 @@ Conformité : voir [`docs/CONFORMITE.md`](../CONFORMITE.md). Chaque offre conser | |||||
| 472 | | [New York Holdings](new_york_holdings.md) | [`breezy`](ats-breezy.md) | 9 | 22 % | 100 % | ✅ | | 472 | | [New York Holdings](new_york_holdings.md) | [`breezy`](ats-breezy.md) | 9 | 22 % | 100 % | ✅ | | ||
| 473 | | [Puma](puma.md) | [`workday`](ats-workday.md) | 9 | 100 % | 100 % | ✅ | | 473 | | [Puma](puma.md) | [`workday`](ats-workday.md) | 9 | 100 % | 100 % | ✅ | | ||
| 474 | | [Quincaillerie Richelieu](richelieu.md) | [`adp`](ats-adp.md) | 9 | 0 % | 100 % | ✅ | | 474 | | [Quincaillerie Richelieu](richelieu.md) | [`adp`](ats-adp.md) | 9 | 0 % | 100 % | ✅ | | ||
| 475 | −| [Strathmore](strathmore.md) | [`adp`](ats-adp.md) | 9 | 44 % | 100 % | ❌ | | 475 | +| [Strathmore](strathmore.md) | [`adp`](ats-adp.md) | 9 | 44 % | 100 % | ✅ | | ||
| 476 | | [Syntronic](syntronic.md) | [`lever`](ats-lever.md) | 9 | 0 % | 100 % | ✅ | | 476 | | [Syntronic](syntronic.md) | [`lever`](ats-lever.md) | 9 | 0 % | 100 % | ✅ | | ||
| 477 | | [Turning Point Brands Canada](recreationmarketing.md) | [`jazzhr`](ats-jazzhr.md) | 9 | 33 % | 100 % | ✅ | | 477 | | [Turning Point Brands Canada](recreationmarketing.md) | [`jazzhr`](ats-jazzhr.md) | 9 | 33 % | 100 % | ✅ | | ||
| 478 | | [Uman Recrutement](umanrecrutement.md) | [`zoho_recruit`](ats-zoho_recruit.md) | 9 | 0 % | 100 % | ✅ | | 478 | | [Uman Recrutement](umanrecrutement.md) | [`zoho_recruit`](ats-zoho_recruit.md) | 9 | 0 % | 100 % | ✅ | | ||
@@ -603,7 +603,7 @@ Conformité : voir [`docs/CONFORMITE.md`](../CONFORMITE.md). Chaque offre conser | |||||
| 603 | | [Aviya Aerospace Systems](aviyatech.md) | [`lever`](ats-lever.md) | 5 | 0 % | 100 % | ✅ | | 603 | | [Aviya Aerospace Systems](aviyatech.md) | [`lever`](ats-lever.md) | 5 | 0 % | 100 % | ✅ | | ||
| 604 | | [BDL Énergie](bdl_energie.md) | [`breezy`](ats-breezy.md) | 5 | 20 % | 20 % | ✅ | | 604 | | [BDL Énergie](bdl_energie.md) | [`breezy`](ats-breezy.md) | 5 | 20 % | 20 % | ✅ | | ||
| 605 | | [Behavox](behavox.md) | [`greenhouse`](ats-greenhouse.md) | 5 | 0 % | 100 % | ✅ | | 605 | | [Behavox](behavox.md) | [`greenhouse`](ats-greenhouse.md) | 5 | 0 % | 100 % | ✅ | | ||
| 606 | −| [Canadian Royalties](canadian_royalties.md) | [`adp`](ats-adp.md) | 5 | 40 % | 100 % | ✅ | | 606 | +| [Canadian Royalties](canadian_royalties.md) | [`adp`](ats-adp.md) | 5 | 40 % | 100 % | ❌ | | ||
| 607 | | [Conagrabrands](conagrabrands.md) | [`workday`](ats-workday.md) | 5 | 80 % | 100 % | ✅ | | 607 | | [Conagrabrands](conagrabrands.md) | [`workday`](ats-workday.md) | 5 | 80 % | 100 % | ✅ | | ||
| 608 | | [Consultant(e) en développement des affaires](omnitrans.md) | [`dayforce`](ats-dayforce.md) | 5 | 40 % | 100 % | ✅ | | 608 | | [Consultant(e) en développement des affaires](omnitrans.md) | [`dayforce`](ats-dayforce.md) | 5 | 40 % | 100 % | ✅ | | ||
| 609 | | [Cultures Gen V](cultures_genv.md) | [`adp`](ats-adp.md) | 5 | 20 % | 100 % | ✅ | | 609 | | [Cultures Gen V](cultures_genv.md) | [`adp`](ats-adp.md) | 5 | 20 % | 100 % | ✅ | | ||
modified
docs/connecteurs/ats-adp.md
+19 −19
@@ -5,14 +5,14 @@ Auteur : Simon-Pierre Boucher | |||||
| 5 | Contact : contact@spboucher.ai | 5 | Contact : contact@spboucher.ai | ||
| 6 | Fichier : docs/connecteurs/ats-adp.md | 6 | Fichier : docs/connecteurs/ats-adp.md | ||
| 7 | Rôle : Fiche plateforme ATS adp — mécanique partagée + tableau des 17 tenants | 7 | Rôle : Fiche plateforme ATS adp — mécanique partagée + tableau des 17 tenants | ||
| 8 | −Généré : 2026-10-31 04:47 EDT par scripts/gen_connector_docs.py — NE PAS ÉDITER, | 8 | +Généré : 2026-10-31 11:33 EDT par scripts/gen_connector_docs.py — NE PAS ÉDITER, | ||
| 9 | relancer le script pour régénérer. | 9 | relancer le script pour régénérer. | ||
| 10 | ============================================================================= | 10 | ============================================================================= | ||
| 11 | --> | 11 | --> | ||
| 12 | 12 | ||||
| 13 | # Plateforme ATS `adp` | 13 | # Plateforme ATS `adp` | ||
| 14 | 14 | ||||
| 15 | −**17 employeurs connectés** via cette plateforme — **131 offres actives**. Module partagé : `jobka/connectors/adp.py` ; un employeur = une sous-classe d'environ 10 lignes. | 15 | +**17 employeurs connectés** via cette plateforme — **120 offres actives**. Module partagé : `jobka/connectors/adp.py` ; un employeur = une sous-classe d'environ 10 lignes. | ||
| 16 | 16 | ||||
| 17 | ## Description & mécanique | 17 | ## Description & mécanique | ||
| 18 | 18 | ||||
@@ -40,23 +40,23 @@ Généré : 2026-10-31 04:47 EDT par scripts/gen_connector_docs.py — NE PAS | |||||
| 40 | 40 | ||||
| 41 | | Employeur | Actives | Salaire | GPS | Mode | Dernier sync | OK | | 41 | | Employeur | Actives | Salaire | GPS | Mode | Dernier sync | OK | | ||
| 42 | |---|---|---|---|---|---|---| | 42 | |---|---|---|---|---|---|---| | ||
| 43 | −| [Groupe Nordik (Nordik Spa-Nature)](groupe_nordik.md) | 19 | 26 % | 100 % | 0 % | 2026-10-31 01:39 | ✅ | | 43 | +| [Uniboard](uniboard.md) | 19 | 32 % | 63 % | 0 % | 2026-10-31 09:35 | ✅ | | ||
| 44 | −| [Uniboard](uniboard.md) | 19 | 32 % | 63 % | 0 % | 2026-10-31 03:19 | ✅ | | 44 | +| [Groupe Nordik (Nordik Spa-Nature)](groupe_nordik.md) | 16 | 25 % | 100 % | 0 % | 2026-10-31 11:17 | ✅ | | ||
| 45 | −| [Quincaillerie Richelieu](richelieu.md) | 17 | 0 % | 71 % | 0 % | 2026-10-31 02:38 | ✅ | | 45 | +| [UV Assurance](uv_assurance.md) | 14 | 0 % | 100 % | 0 % | 2026-10-31 09:35 | ✅ | | ||
| 46 | −| [UV Assurance](uv_assurance.md) | 14 | 0 % | 100 % | 0 % | 2026-10-31 04:47 | ✅ | | 46 | +| [Cook It](cookit.md) | 10 | 60 % | 100 % | 0 % | 2026-10-31 11:04 | ✅ | | ||
| 47 | −| [Cook It](cookit.md) | 10 | 60 % | 100 % | 0 % | 2026-10-31 01:26 | ✅ | | 47 | +| [H2O Innovation](h2o_innovation.md) | 9 | 0 % | 100 % | 0 % | 2026-10-31 11:23 | ✅ | | ||
| 48 | −| [H2O Innovation](h2o_innovation.md) | 9 | 0 % | 100 % | 0 % | 2026-10-31 01:47 | ✅ | | 48 | +| [Strathmore](strathmore.md) | 9 | 44 % | 100 % | 0 % | 2026-10-31 11:33 | ✅ | | ||
| 49 | −| [Strathmore](strathmore.md) | 9 | 44 % | 100 % | 0 % | 2026-10-31 03:00 | ✅ | | 49 | +| [Quincaillerie Richelieu](richelieu.md) | 9 | 0 % | 100 % | 0 % | 2026-10-31 09:24 | ✅ | | ||
| 50 | −| [Bento Sushi](bento_sushi.md) | 8 | 88 % | 100 % | 0 % | 2026-10-31 04:40 | ✅ | | 50 | +| [Bento Sushi](bento_sushi.md) | 8 | 88 % | 100 % | 0 % | 2026-10-31 10:46 | ✅ | | ||
| 51 | −| [MSI Gestion immobilière](msi_gestion.md) | 6 | 100 % | 100 % | 50 % | 2026-10-31 02:12 | ✅ | | 51 | +| [MSI Gestion immobilière](msi_gestion.md) | 6 | 100 % | 100 % | 50 % | 2026-10-31 09:17 | ✅ | | ||
| 52 | −| [Abritek](abritek.md) | 6 | 100 % | 100 % | 0 % | 2026-10-31 04:33 | ✅ | | 52 | +| [Abritek](abritek.md) | 6 | 100 % | 100 % | 0 % | 2026-10-31 10:39 | ✅ | | ||
| 53 | −| [Cultures Gen V](cultures_genv.md) | 5 | 20 % | 100 % | 0 % | 2026-10-31 01:27 | ✅ | | 53 | +| [Cultures Gen V](cultures_genv.md) | 5 | 20 % | 100 % | 0 % | 2026-10-31 11:05 | ✅ | | ||
| 54 | −| [Canadian Royalties](canadian_royalties.md) | 5 | 40 % | 100 % | 0 % | 2026-10-31 04:42 | ❌ | | 54 | +| [Canadian Royalties](canadian_royalties.md) | 5 | 40 % | 100 % | 0 % | 2026-10-31 10:48 | ❌ | | ||
| 55 | −| [Mitsubishi HC Capital Canada](mitsubishi_hc_capital.md) | 1 | 0 % | 100 % | 0 % | 2026-10-31 02:08 | ✅ | | 55 | +| [Mitsubishi HC Capital Canada](mitsubishi_hc_capital.md) | 1 | 0 % | 100 % | 0 % | 2026-10-31 09:16 | ✅ | | ||
| 56 | −| [Osgoode Properties](osgoode_properties.md) | 1 | 100 % | 100 % | 0 % | 2026-10-31 04:32 | ✅ | | 56 | +| [Osgoode Properties](osgoode_properties.md) | 1 | 100 % | 100 % | 0 % | 2026-10-31 09:19 | ✅ | | ||
| 57 | −| [Nemaska Lithium](nemaska_lithium.md) | 1 | 0 % | 100 % | 0 % | 2026-10-31 02:15 | ✅ | | 57 | +| [Nemaska Lithium](nemaska_lithium.md) | 1 | 0 % | 100 % | 0 % | 2026-10-31 09:17 | ✅ | | ||
| 58 | −| [Triple Boris](triple_boris.md) | 1 | 0 % | 100 % | 0 % | 2026-10-31 03:15 | ✅ | | 58 | +| [Triple Boris](triple_boris.md) | 1 | 0 % | 100 % | 0 % | 2026-10-31 09:34 | ✅ | | ||
| 59 | −| [Niobec (Magris Performance Materials)](niobec.md) | 0 | — | — | — | 2026-10-31 04:03 | ✅ | | 59 | +| [Niobec (Magris Performance Materials)](niobec.md) | 0 | — | — | — | 2026-10-31 09:17 | ✅ | | ||
| 60 | 60 | ||||
| 61 | ## Licence / conformité | 61 | ## Licence / conformité | ||
| 62 | 62 | ||||
modified
docs/connecteurs/strathmore.md
+19 −18
@@ -5,7 +5,7 @@ Auteur : Simon-Pierre Boucher | |||||
| 5 | Contact : contact@spboucher.ai | 5 | Contact : contact@spboucher.ai | ||
| 6 | Fichier : docs/connecteurs/strathmore.md | 6 | Fichier : docs/connecteurs/strathmore.md | ||
| 7 | Rôle : Fiche connecteur — Strathmore (employeur direct, ATS adp) | 7 | Rôle : Fiche connecteur — Strathmore (employeur direct, ATS adp) | ||
| 8 | −Généré : 2026-10-23 11:14 EDT par scripts/gen_connector_docs.py — NE PAS ÉDITER, | 8 | +Généré : 2026-10-31 11:33 EDT par scripts/gen_connector_docs.py — NE PAS ÉDITER, | ||
| 9 | relancer le script pour régénérer. | 9 | relancer le script pour régénérer. | ||
| 10 | ============================================================================= | 10 | ============================================================================= | ||
| 11 | --> | 11 | --> | ||
@@ -38,7 +38,7 @@ Généré : 2026-10-23 11:14 EDT par scripts/gen_connector_docs.py — NE PAS | |||||
| 38 | 38 | ||||
| 39 | ## Champs → schéma | 39 | ## Champs → schéma | ||
| 40 | 40 | ||||
| 41 | −Complétude mesurée sur les **12 offres actives** de la source (base live, 2026-10-23 11:14 EDT). | 41 | +Complétude mesurée sur les **9 offres actives** de la source (base live, 2026-10-31 11:33 EDT). | ||
| 42 | 42 | ||||
| 43 | | Champ (`jobs.*`) | Rôle | Complétude | | 43 | | Champ (`jobs.*`) | Rôle | Complétude | | ||
| 44 | |---|---|---| | 44 | |---|---|---| | ||
@@ -50,21 +50,21 @@ Complétude mesurée sur les **12 offres actives** de la source (base live, 2026 | |||||
| 50 | | `region` — Région | région administrative | 100 % | | 50 | | `region` — Région | région administrative | 100 % | | ||
| 51 | | `address` — Adresse | adresse du lieu de travail | 0 % | | 51 | | `address` — Adresse | adresse du lieu de travail | 0 % | | ||
| 52 | | `postal_code` — Code postal | code postal si publié | 100 % | | 52 | | `postal_code` — Code postal | code postal si publié | 100 % | | ||
| 53 | −| `work_mode` — Mode | presentiel / hybride / teletravail | 8 % | | 53 | +| `work_mode` — Mode | presentiel / hybride / teletravail | 0 % | | ||
| 54 | −| `employment_type` — Type | temps_plein / temps_partiel / … | 67 % | | 54 | +| `employment_type` — Type | temps_plein / temps_partiel / … | 56 % | | ||
| 55 | −| `salary` — Salaire ($) | bornes numériques normalisées $/h et $/an | 42 % | | 55 | +| `salary` — Salaire ($) | bornes numériques normalisées $/h et $/an | 44 % | | ||
| 56 | | `salary_label` — Libellé salaire | texte salarial original | 0 % | | 56 | | `salary_label` — Libellé salaire | texte salarial original | 0 % | | ||
| 57 | | `benefits` — Avantages | avantages sociaux publiés (JSON) | 0 % | | 57 | | `benefits` — Avantages | avantages sociaux publiés (JSON) | 0 % | | ||
| 58 | −| `requirements` — Exigences | scolarité, expérience, langues (JSON) | 75 % | | 58 | +| `requirements` — Exigences | scolarité, expérience, langues (JSON) | 67 % | | ||
| 59 | | `date_posted` — Date de parution | ISO 8601 | 100 % | | 59 | | `date_posted` — Date de parution | ISO 8601 | 100 % | | ||
| 60 | | `date_deadline` — Date limite | date limite pour postuler | 0 % | | 60 | | `date_deadline` — Date limite | date limite pour postuler | 0 % | | ||
| 61 | −| `category` — Catégorie | taxonomie interne (TI, Santé, …) | 50 % | | 61 | +| `category` — Catégorie | taxonomie interne (TI, Santé, …) | 56 % | | ||
| 62 | | `language` — Langue | fr / en / bilingue (source ou heuristique) | 100 % | | 62 | | `language` — Langue | fr / en / bilingue (source ou heuristique) | 100 % | | ||
| 63 | | `company_logo` — Logo employeur | URL du logo si exposé par la source | 0 % | | 63 | | `company_logo` — Logo employeur | URL du logo si exposé par la source | 0 % | | ||
| 64 | | `apply_url` — Candidature | lien de candidature directe | 0 % | | 64 | | `apply_url` — Candidature | lien de candidature directe | 0 % | | ||
| 65 | −| `gps` — GPS | lat/lng (géocodage sans invention) | 92 % | | 65 | +| `gps` — GPS | lat/lng (géocodage sans invention) | 100 % | | ||
| 66 | 66 | ||||
| 67 | −Exemple réel : *Opérateur(trice)* — Gatineau · ∅ · parue le 2026-10-23. | 67 | +Exemple réel : *Directeur national, santé, sécurité et environnement (SSE) – Can* — Montréal · ∅ · parue le 2026-10-27. | ||
| 68 | 68 | ||||
| 69 | ## Fréquence & budgets | 69 | ## Fréquence & budgets | ||
| 70 | 70 | ||||
@@ -79,15 +79,15 @@ Exemple réel : *Opérateur(trice)* — Gatineau · ∅ · parue le 2026-10-23. | |||||
| 79 | 79 | ||||
| 80 | ## Volumétrie & complétude live | 80 | ## Volumétrie & complétude live | ||
| 81 | 81 | ||||
| 82 | −*(mesuré le 2026-10-23 11:14 EDT dans `data/jobka.db`)* | 82 | +*(mesuré le 2026-10-31 11:33 EDT dans `data/jobka.db`)* | ||
| 83 | 83 | ||||
| 84 | −- **Offres en base** : 26 (dont **12 actives**, 0 masquées comme doublons `dup_of`) | 84 | +- **Offres en base** : 26 (dont **9 actives**, 0 masquées comme doublons `dup_of`) | ||
| 85 | −- **Salaire** : 5/12 actives (42 %) | 85 | +- **Salaire** : 4/9 actives (44 %) | ||
| 86 | −- **GPS** : 11/12 actives (92 %) | 86 | +- **GPS** : 9/9 actives (100 %) | ||
| 87 | −- **Mode** : 1/12 actives (8 %) | 87 | +- **Mode** : 0/9 actives (0 %) | ||
| 88 | −- **Parution** : 12/12 actives (100 %) | 88 | +- **Parution** : 9/9 actives (100 %) | ||
| 89 | −- **Dernier sync** : 2026-10-23 11:14 — trouvées 12, +1, ~0, -0 | 89 | +- **Dernier sync** : 2026-10-31 11:33 — trouvées 9, +0, ~0, -0 | ||
| 90 | −- **Syncs enregistrés** (`sync_log`) : 529 | 90 | +- **Syncs enregistrés** (`sync_log`) : 595 | ||
| 91 | 91 | ||||
| 92 | ## Erreurs & dépannage | 92 | ## Erreurs & dépannage | ||
| 93 | 93 | ||||
@@ -95,7 +95,7 @@ Erreurs relevées dans `sync_log` : | |||||
| 95 | 95 | ||||
| 96 | | Erreur | Occurrences | Dernière fois | | 96 | | Erreur | Occurrences | Dernière fois | | ||
| 97 | |---|---|---| | 97 | |---|---|---| | ||
| 98 | −| 404 Client Error: Not Found for url: https://workforcenow.adp.com/mascsr/default/careercen… | 2 | 2026-10-23 09:57 | | 98 | +| 404 Client Error: Not Found for url: https://workforcenow.adp.com/mascsr/default/careercen… | 4 | 2026-10-31 09:30 | | ||
| 99 | | Expecting value: line 1 column 1 (char 0) | 4 | 2026-08-30 01:22 | | 99 | | Expecting value: line 1 column 1 (char 0) | 4 | 2026-08-30 01:22 | | ||
| 100 | 100 | ||||
| 101 | - Rejouer un sync isolé : `.venv/bin/python run.py sync strathmore` puis inspecter `sync_log` : `sqlite3 data/jobka.db "SELECT * FROM sync_log WHERE source='strathmore' ORDER BY ts DESC LIMIT 5;"` | 101 | - Rejouer un sync isolé : `.venv/bin/python run.py sync strathmore` puis inspecter `sync_log` : `sqlite3 data/jobka.db "SELECT * FROM sync_log WHERE source='strathmore' ORDER BY ts DESC LIMIT 5;"` | ||
@@ -117,6 +117,7 @@ Erreurs relevées dans `sync_log` : | |||||
| 117 | 117 | ||||
| 118 | Commits touchant `jobka/connectors/strathmore.py` : | 118 | Commits touchant `jobka/connectors/strathmore.py` : | ||
| 119 | 119 | ||||
| 120 | +- `1444de7f` 2026-10-23 [ka6] connecteur strathmore: stale = faux positif, second blip 404 ADP WFN isolé — rien à réparer. Après la fenêtre systémique nocturne 00:35→01:54 EDT du 2026-10-23 (6 tenants ADP en 404, strathmore touché à 00:41 puis reverdi seul à 03:15 found=11), un SECOND 404 isolé a frappé strathmore seul à 09:57 EDT sur l'endpoint job-requisitions (les 6 frères ADP tous verts 08:34→10:03 : pas systémique cette fois). Le seuil stale de 4 h a été franchi à 11:09 (dernier succès 07:09) juste avant la rotation suivante. Le repli « détail seulement » du connecteur ne s'engage volontairement pas sur un 4xx franc — comportement conservé. Endpoint re-vérifié live 200 JSON via curl à 11:13 (totalNumber=14), sync isolé rejoué : ok=1 found=12 (médiane 11.0) en 4,3 s, 12 offres QC actives avec ville/région (11/12 GPS, la nouvelle offre sera géocodée au prochain lot). Aucun code de fetch modifié, docstring chronologie seulement ; fiches strathmore.md/ats-adp.md/INDEX.md régénérées (1131 autres fiches restaurées, hors périmètre). 108 tests verts, pm2 restart job-ka-sync OK, site local 200, www.job-ka.com 200. | ||||
| 120 | - `4dcbd45b` 2026-08-30 [ka6] snapshot pré-mission bento_sushi | 121 | - `4dcbd45b` 2026-08-30 [ka6] snapshot pré-mission bento_sushi | ||
| 121 | - `93fed9a9` 2026-08-29 Revert "[ka6] snapshot pré-mission triple_boris" | 122 | - `93fed9a9` 2026-08-29 Revert "[ka6] snapshot pré-mission triple_boris" | ||
| 122 | - `ba40d49a` 2026-08-29 [ka6] snapshot pré-mission triple_boris | 123 | - `ba40d49a` 2026-08-29 [ka6] snapshot pré-mission triple_boris | ||
modified
jobka/connectors/strathmore.py
+55 −2
@@ -5,11 +5,31 @@ | |||||
| 5 | # Fichier : jobka/connectors/strathmore.py | 5 | # Fichier : jobka/connectors/strathmore.py | ||
| 6 | # Rôle : Connecteur Strathmore — produits d'entretien, Saint-Hyacinthe — | 6 | # Rôle : Connecteur Strathmore — produits d'entretien, Saint-Hyacinthe — | ||
| 7 | # ADP WFN + repli « détail seulement » quand l'API liste échoue | 7 | # ADP WFN + repli « détail seulement » quand l'API liste échoue | ||
| 8 | −# (maintenances nocturnes ADP) | 8 | +# (maintenances nocturnes ADP) + garde-fou retry borné (frontal | ||
| 9 | −# Créé : 2026-08-25 Modifié : 2026-10-23 | 9 | +# ADP intermittent par cid) | ||
| 10 | +# Créé : 2026-08-25 Modifié : 2026-10-31 | ||||
| 10 | # ============================================================================= | 11 | # ============================================================================= | ||
| 11 | """Strathmore — ADP Workforce Now, avec repli de revalidation. | 12 | """Strathmore — ADP Workforce Now, avec repli de revalidation. | ||
| 12 | 13 | ||||
| 14 | +Chronologie (mission ka6 2026-10-31) : 7e tenant ADP de l'app touché par le | ||||
| 15 | +frontal intermittent PAR CID (même panne que bento_sushi 64f53c8f, cookit | ||||
| 16 | +7873198d, mitsubishi_hc_capital du 2026-10-26, niobec 61a2ddf8, | ||||
| 17 | +osgoode_properties 3b95c432 et uv_assurance 946898d9 — pool backend malade | ||||
| 18 | +côté ADP, « default backend - 404 » nginx). Vert found=9 en continu (= la | ||||
| 19 | +médiane 9.0), puis 404 franc sur la liste fr_CA à 23:57 le 30/10 (épisode | ||||
| 20 | +nocturne multi-tenants 23:45→04:42) ; reverdi seul à 03:00 et 06:49, puis | ||||
| 21 | +NOUVEAU 404 isolé à 09:30 → stale. Sonde live 10:5x : sur 6 essais sur la | ||||
| 22 | +MÊME URL liste à la même minute, 3 × 200 JSON (totalNumber=10) et | ||||
| 23 | +3 × « default backend - 404 » de 21 octets — intermittence, tenant VIVANT, | ||||
| 24 | +aucune migration. Garde-fou répliqué des six frères : `_get_json` retente | ||||
| 25 | +jusqu'à 30 fois (pause 2 s) sur 404/502/503/504/timeout/non-JSON, timeout | ||||
| 26 | +abaissé 30→15 s pour borner les connexions qui pendent. Dormant dès que le | ||||
| 27 | +frontal est sain (1er essai OK = zéro surcoût) ; un sync vert ne coûte | ||||
| 28 | +qu'UN appel liste (détails en cache BD). NE PAS retirer ce garde-fou si un | ||||
| 29 | +futur scan le croise : il est inerte hors panne. Il couvre liste ET détail | ||||
| 30 | +(_fetch_detail passe par _get_json) ; le repli « détail seulement » | ||||
| 31 | +ci-dessous reste la défense contre les maintenances totales sorry.adp.com. | ||||
| 32 | + | ||||
| 13 | Chronologie 2026-10-23 : après la fenêtre systémique nocturne 00:35→01:54 EDT | 33 | Chronologie 2026-10-23 : après la fenêtre systémique nocturne 00:35→01:54 EDT | ||
| 14 | (6 tenants ADP en « 404 Not Found » franc sur job-requisitions, dont strathmore | 34 | (6 tenants ADP en « 404 Not Found » franc sur job-requisitions, dont strathmore | ||
| 15 | à 00:41 — reverdi seul à 03:15), un SECOND 404 isolé a frappé strathmore seul à | 35 | à 00:41 — reverdi seul à 03:15), un SECOND 404 isolé a frappé strathmore seul à | ||
@@ -41,6 +61,8 @@ liste normal reprend seul au cycle suivant la fin de la maintenance. | |||||
| 41 | """ | 61 | """ | ||
| 42 | from __future__ import annotations | 62 | from __future__ import annotations | ||
| 43 | 63 | ||||
| 64 | +import time | ||||
| 65 | + | ||||
| 44 | import requests | 66 | import requests | ||
| 45 | 67 | ||||
| 46 | from ..schema import JobPosting, clean_html | 68 | from ..schema import JobPosting, clean_html | ||
@@ -53,6 +75,37 @@ class StrathmoreConnector(ADPWorkforceNowConnector): | |||||
| 53 | CID = "e6cc8038-8e63-4af3-af60-97ea91f1747c" | 75 | CID = "e6cc8038-8e63-4af3-af60-97ea91f1747c" | ||
| 54 | CCID = "19000101_000001" | 76 | CCID = "19000101_000001" | ||
| 55 | 77 | ||||
| 78 | + # Frontal ADP intermittent pour CE tenant (2026-10-31) : mêmes bornes que | ||||
| 79 | + # bento_sushi/cookit/mitsubishi_hc_capital/niobec/osgoode_properties/ | ||||
| 80 | + # uv_assurance — les 404 échouent vite (<1 s), le timeout court borne les | ||||
| 81 | + # connexions qui pendent, et un sync vert ne coûte qu'UN appel liste | ||||
| 82 | + # (détails en cache BD). | ||||
| 83 | + timeout = 15 | ||||
| 84 | + _FLAKY_TRIES = 30 | ||||
| 85 | + _FLAKY_PAUSE = 2.0 | ||||
| 86 | + | ||||
| 87 | + def _get_json(self, url: str, params: dict) -> dict: | ||||
| 88 | + last: Exception | None = None | ||||
| 89 | + for attempt in range(self._FLAKY_TRIES): | ||||
| 90 | + if attempt: | ||||
| 91 | + time.sleep(self._FLAKY_PAUSE) | ||||
| 92 | + try: | ||||
| 93 | + return super()._get_json(url, params) | ||||
| 94 | + except requests.HTTPError as exc: | ||||
| 95 | + status = getattr(exc.response, "status_code", None) | ||||
| 96 | + if status not in (404, 502, 503, 504): | ||||
| 97 | + raise | ||||
| 98 | + last = exc | ||||
| 99 | + except (requests.Timeout, requests.ConnectionError) as exc: | ||||
| 100 | + last = exc | ||||
| 101 | + except RuntimeError as exc: | ||||
| 102 | + # « ADP non-JSON après 3 essais » de la classe de base : | ||||
| 103 | + # même frontal malade, même traitement. | ||||
| 104 | + if not str(exc).startswith("ADP non-JSON"): | ||||
| 105 | + raise | ||||
| 106 | + last = exc | ||||
| 107 | + raise last | ||||
| 108 | + | ||||
| 56 | def fetch(self) -> list[JobPosting]: | 109 | def fetch(self) -> list[JobPosting]: | ||
| 57 | try: | 110 | try: | ||
| 58 | return super().fetch() | 111 | return super().fetch() | ||
| 59 | 112 | ||||