SPB Git forge

spb/job-ka

Public
229commits 1branches 0releases
38.1 MBsize
maindefault branch
1 h agolast push
HTML 82.1% Python 14.6% TypeScript 1.9% CSS 1% JavaScript 0.5%

[ka6] fix connecteur altusgroup: external_id régional → ID de réquisition (hook _external_id dans la plateforme workday, défaut inchangé) — le tenant altusgroup.wd3 préfixe bulletFields par la région quand il y en a une (['Ontario','R0013639'] vs ['R0013942'] seul), si bien que bullets[0] devenait l'external_id : l'offre QC historique était en base sous external_id='Quebec', et le sync du 2026-08-26 trouvait 2 offres pour 1 seule stockée (collision d'ID entre postes d'une même région). L'extraction est désormais isolée dans un hook _external_id() de WorkdayConnector (comportement par défaut strictement identique pour les autres tenants) et surchargée dans altusgroup.py : premier bullet au format réquisition R+chiffres, sinon suffixe du chemin. Vérifié live : 36 postes scannés → 36 IDs uniques au format R00xxxxx, 0 poste non conforme. Volume 0 légitime AUJOURD'HUI : 7 postes Canada, tous Toronto — aucune offre QC depuis la dépublication de l'offre montréalaise le 2026-08-26 (médiane historique 0.0). Le statut stale vient de là (la supervision date le dernier succès au dernier sync found>0, 2026-08-26 14:19) ; l'unique échec récent (2026-09-12 03:04, « Workday non-JSON HTTP 200 text/html ») est la fenêtre de maintenance hebdomadaire Workday du vendredi/samedi nuit (28 occurrences multi-sources cette nuit, mêmes plages 02h30–03h15 les 2026-08-29 et 2026-09-05), transitoire et déjà retryée. Sync isolé rejoué : found=0 en 2,4 s, statut ok. 101 tests pytest verts. pm2 restart job-ka-sync OK, site 200.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Simon-Pierre Boucher committed 12 days ago (Sep 12, 2026) parent d333936

2 changed files +28 −4

modified jobka/connectors/altusgroup.py +17 −1
@@ -5,8 +5,10 @@
5 5 # Fichier : jobka/connectors/altusgroup.py
6 6 # Rôle : Connecteur Groupe Altus — workday (tenant altusgroup.wd3, site AltusGroup)
7 7 # [généré par scripts/gen_connectors.py, flux vérifié le 2026-08-25]
8 −# Créé : 2026-08-25 Modifié : 2026-08-25
8 +# Créé : 2026-08-25 Modifié : 2026-09-12
9 9 # =============================================================================
10 +import re
11 +
10 12 from .workday import WorkdayConnector
11 13
12 14
@@ -16,3 +18,17 @@ class AltusgroupConnector(WorkdayConnector):
16 18 TENANT = 'altusgroup'
17 19 HOST = 'wd3'
18 20 SITE = 'AltusGroup'
21 +
22 + # Ce tenant préfixe bulletFields par la région quand il y en a une :
23 + # ["Ontario", "R0013639"] ou ["R0013942"] seul. bullets[0] donnait donc
24 + # « Quebec » comme external_id (collision entre postes d'une même région,
25 + # constatée le 2026-08-26 : 2 offres trouvées, 1 seule en base). On prend
26 + # le bullet au format réquisition (R + chiffres), sinon le suffixe du
27 + # chemin (qui peut porter un suffixe de variante, ex. R0013801-1).
28 + _REQ_ID = re.compile(r'^R\d+(?:-\d+)?$')
29 +
30 + def _external_id(self, item: dict, path: str) -> str:
31 + for b in item.get('bulletFields') or []:
32 + if self._REQ_ID.match(str(b).strip()):
33 + return str(b).strip()
34 + return path.rsplit('_', 1)[-1]
modified jobka/connectors/workday.py +11 −3
@@ -5,7 +5,7 @@
5 5 # Fichier : jobka/connectors/workday.py
6 6 # Rôle : Classe de plateforme Workday (API JSON publique wday/cxs) — un
7 7 # employeur = une sous-classe de ~10 lignes (TENANT, HOST, SITE)
8 −# Créé : 2026-08-17 Modifié : 2026-09-10
8 +# Créé : 2026-08-17 Modifié : 2026-09-12
9 9 # =============================================================================
10 10 """Plateforme Workday.
11 11
@@ -245,6 +245,15 @@ class WorkdayConnector(BaseConnector):
245 245 except Exception:
246 246 continue # facette indisponible : on n'invente rien
247 247
248 + def _external_id(self, item: dict, path: str) -> str:
249 + """Identifiant externe d'une ligne de liste — par défaut le premier
250 + `bulletFields` (= req_id chez la plupart des tenants), sinon le
251 + suffixe du chemin. Hook surchargeable : certains tenants (ex.
252 + altusgroup) préfixent les bullets par la région, ce qui provoque des
253 + collisions d'ID si on prend bullets[0] aveuglément."""
254 + bullets = item.get("bulletFields") or []
255 + return str((bullets[0] if bullets else "") or path.rsplit("_", 1)[-1])
256 +
248 257 def _fetch_detail(self, external_path: str) -> dict:
249 258 data = self._req_json("get",
250 259 f"{self._base}/wday/cxs/{self.TENANT}"
@@ -272,8 +281,7 @@ class WorkdayConnector(BaseConnector):
272 281 if not self._server_filtered and not self._keep(item):
273 282 continue
274 283 path = item.get("externalPath") or ""
275 − bullets = item.get("bulletFields") or []
276 − eid = (bullets[0] if bullets else "") or path.rsplit("_", 1)[-1]
284 + eid = self._external_id(item, path)
277 285 if not eid or not path:
278 286 continue
279 287 job = JobPosting(
280 288