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 solmentalhealth: faux positif du filtre Québec — « Quebec St. » (nom de rue à Denver) matchait \bquebec\b — le statut stale vient de la dépublication NORMALE de l'unique offre du tenant (Psychiatric Clinician, id 4704220005, 404 live, retirée à 16:08 miss_count=2 → active=0), mais cette offre n'aurait JAMAIS dû être publiée : son lieu réel est « 3401 Quebec St. Suite 8000, Denver, CO, 80207 » (bureau de SOL Mental Health sur Quebec Street à Denver), classé ville=Québec/Capitale-Nationale et géocodé à Québec parce que _QC_MARKERS (\bquebec\b) est évalué avant le rejet _NON_QC_REGION_RE (« , CO ») dans is_quebec_location. La médiane historique 1.0 est donc elle-même un artefact : le bon volume QC de ce tenant est 0 (vérifié live : API Greenhouse 200, 65 offres, toutes aux États-Unis — NY/VA/MD/CO/DC). Correctif : nouveau _QUEBEC_STREET_RE — « quebec » suivi d'un type de voie anglophone (st/street/ave/blvd/rd/dr/ct/ln/way/pl/hwy/pkwy…) = nom de rue, neutralisé avant tout matching dans is_quebec_location ET parse_location ; le garde (?!-) préserve les abréviations de saints des libellés QC légitimes vérifiés en base (« CAN Quebec St-Hubert/St-Laurent/St-Hyacinthe/Ste-Thérèse », agropur). Tests unitaires ajoutés (4 rues US rejetées, libellés agropur et QC classiques conservés). Correction au passage du même artefact sources.json que samsara/delos_data/findevcanada/dupont : url vide → https://www.solmentalhealth.com (la fiche affichait « Site : []() »). Sync isolé rejoué post-patch : found=0 en 0,2 s, ok — 0 est le volume légitime, l'offre Denver ne reviendra plus même si republiée. 104 tests pytest verts. pm2 restart job-ka-sync OK, site 200.

Simon-Pierre Boucher committed 10 days ago (Sep 14, 2026) parent 5cf2a52

3 changed files +27 −5

modified data/sources.json +1 −1
@@ -7515,7 +7515,7 @@
7515 7515 {
7516 7516 "id": "solmentalhealth",
7517 7517 "name": "SOL Mental Health",
7518 − "url": "",
7518 + "url": "https://www.solmentalhealth.com",
7519 7519 "careers_url": "https://job-boards.greenhouse.io/solmentalhealth",
7520 7520 "sectors": [
7521 7521 "Santé",
modified jobka/normalize.py +12 −3
@@ -6,7 +6,7 @@
6 6 # Rôle : Normalisation commune des offres (salaires, dates, mode/type
7 7 # d'emploi, lieu, catégorie, exigences, séniorité) — jamais de
8 8 # valeur inventée
9 −# Créé : 2026-08-17 Modifié : 2026-09-12
9 +# Créé : 2026-08-17 Modifié : 2026-09-14
10 10 # =============================================================================
11 11 """Couche de normalisation commune appelée par JobPosting.finalize().
12 12
@@ -436,6 +436,15 @@ _QC_MARKERS = re.compile(
436 436 r"\bqc\b|\bquebec\b|\bqu[e]bec, canada\b|province de quebec", re.I)
437 437 _POSTAL_RE = re.compile(r"\b([GHJ]\d[A-Z])\s*(\d[A-Z]\d)\b", re.I) # G/H/J = Québec
438 438
439 +# « Quebec » suivi d'un type de voie anglophone = nom de RUE, pas la province
440 +# (« 3401 Quebec St. Suite 8000, Denver, CO » — bug solmentalhealth 2026-09-14 :
441 +# offre de Denver publiée comme Québec/Capitale-Nationale). Neutralisé avant
442 +# tout matching de marqueur/ville. Le (?!-) protège les abréviations de saints
443 +# des libellés québécois légitimes (« CAN Quebec St-Hubert », « Ste-Thérèse »).
444 +_QUEBEC_STREET_RE = re.compile(
445 + r"\bquebec\s+(?:st|street|ave|avenue|blvd|boulevard|rd|road|dr|drive|"
446 + r"ct|court|ln|lane|way|pl|place|hwy|highway|pkwy|parkway)\b\.?(?!-)")
447 +
439 448 # Villes canadiennes hors Québec (et grandes villes étrangères) fréquentes
440 449 # dans les flux pancanadiens/mondiaux — jamais des villes d'offres
441 450 # québécoises : à rejeter lors du parsing de lieu (clés sans accents).
@@ -493,7 +502,7 @@ def parse_location(raw: str) -> dict:
493 502 m = _POSTAL_RE.search(s)
494 503 if m:
495 504 out["postal_code"] = f"{m.group(1).upper()} {m.group(2).upper()}"
496 − key = _key(s)
505 + key = _QUEBEC_STREET_RE.sub(" ", _key(s))
497 506 for ck, city in _QC_CITIES.items():
498 507 if re.search(rf"(?<![a-z]){re.escape(ck)}(?![a-z])", key):
499 508 out["city"] = city
@@ -533,7 +542,7 @@ _NON_QC_REGION_RE = re.compile(
533 542
534 543 def is_quebec_location(raw: str) -> bool:
535 544 """Vrai si le libellé pointe vers le Québec (filtre des ATS pancanadiens)."""
536 − key = _key(clean_text(raw))
545 + key = _QUEBEC_STREET_RE.sub(" ", _key(clean_text(raw)))
537 546 if not key:
538 547 return False
539 548 if key in _NON_QC_CITIES: # libellé = ville canadienne/monde hors QC
modified tests/test_normalize.py +14 −1
@@ -5,7 +5,7 @@
5 5 # Fichier : tests/test_normalize.py
6 6 # Rôle : Tests unitaires de la couche de normalisation (salaires, dates,
7 7 # mode/type d'emploi, lieux, catégories)
8 −# Créé : 2026-08-17 Modifié : 2026-09-12
8 +# Créé : 2026-08-17 Modifié : 2026-09-14
9 9 # =============================================================================
10 10 import datetime as dt
11 11
@@ -163,6 +163,19 @@ def test_is_quebec_location():
163 163 assert not is_quebec_location("Richmond, BC")
164 164 assert not is_quebec_location("Paris, IDF, France")
165 165 assert not is_quebec_location("")
166 + # « Quebec St./Street/Ave » = nom de RUE hors Québec, pas la province (bug
167 + # solmentalhealth 2026-09-14 : bureau de Denver sur Quebec Street publié
168 + # comme Québec/Capitale-Nationale — le marqueur \bquebec\b gagnait avant
169 + # le rejet « , CO »)
170 + assert not is_quebec_location("3401 Quebec St. Suite 8000, Denver, CO, 80207")
171 + assert not is_quebec_location("3401 Quebec St. Suite 8000")
172 + assert not is_quebec_location("2600 Quebec Street NW, Washington, DC")
173 + assert not is_quebec_location("Quebec Ave, Golden Valley, MN")
174 + # …mais les abréviations de saints des libellés QC légitimes survivent
175 + assert is_quebec_location("CAN Quebec St-Hubert")
176 + assert is_quebec_location("CAN Quebec Ste-Thérèse")
177 + assert is_quebec_location("CAN Quebec Plessisville")
178 + assert not parse_location("3401 Quebec St. Suite 8000, Denver, CO, 80207")["region"]
166 179
167 180
168 181 # --- catégories / HTML ------------------------------------------------------------
169 182