SPB Git forge

spb/job-ka

Public
227commits 1branches 0releases
37.7 MBsize
maindefault branch
2 h agolast push
HTML 82.1% Python 14.6% TypeScript 1.9% CSS 1% JavaScript 0.5%
9.3 KB · 118 lines markdown
Rendered Raw Blame History
1<!--2=============================================================================3Job·Ka — Groupe KA4Auteur  : Simon-Pierre Boucher5Contact : contact@spboucher.ai6Fichier : docs/connecteurs/lassonde.md7Rôle    : Fiche connecteur — Industries Lassonde (employeur direct, ATS custom)8Généré  : 2026-09-21 18:06 EDT par scripts/gen_connector_docs.py — NE PAS ÉDITER,9          relancer le script pour régénérer.10=============================================================================11-->1213# Industries Lassonde (`lassonde`)1415**Employeur direct** · Plateforme ATS : [`custom`](ats-custom.md) · Statut registre : actif · Connecteur : `jobka/connectors/lassonde.py`1617## Description1819- **Site** : [Industries Lassonde](https://www.lassonde.com)20- **Page carrières** : https://www.lassonde.com/fr/emplois/21- **Secteurs** : Agroalimentaire, Fabrication22- **Région** : Rougemont, Montréal23- Offres marquées **« Offre directe »** dans l'app (badge) : la candidature se fait chez l'employeur, jamais via un intermédiaire.2425## Accès2627- **Mécanique** : voir la fiche plateforme [`ats-custom.md`](ats-custom.md) — API JSON publique du site carrières, backend `requests` direct (Scrapfly seulement si indiqué sur la fiche plateforme).28- **Identifiants du tenant** (attributs du connecteur) :2930| Attribut | Valeur |31|---|---|32| `EMPLOYER` | `Industries Lassonde` |33| `LIST_URL` | `https://www.lassonde.com/fr/emplois/` |34- **Throttle** : 1.0 s entre requêtes.35- **Filtre Québec** : seuls les postes localisés au Québec sont conservés (facette serveur quand l'ATS en offre une, sinon `is_quebec_location` côté client).3637## Champs → schéma3839Complétude mesurée sur les **33 offres actives** de la source (base live, 2026-09-21 18:06 EDT).4041| Champ (`jobs.*`) | Rôle | Complétude |42|---|---|---|43| `title` — Titre | titre du poste | 100 % |44| `employer` — Employeur | nom de l'entreprise | 100 % |45| `url` — URL | lien direct vers l'offre originale | 100 % |46| `description` — Description | texte complet (HTML nettoyé) | 100 % |47| `city` — Ville | municipalité normalisée | 100 % |48| `region` — Région | région administrative | 100 % |49| `address` — Adresse | adresse du lieu de travail | 0 % |50| `postal_code` — Code postal | code postal si publié | 0 % |51| `work_mode` — Mode | presentiel / hybride / teletravail | 6 % |52| `employment_type` — Type | temps_plein / temps_partiel / … | 9 % |53| `salary` — Salaire ($) | bornes numériques normalisées $/h et $/an | 33 % |54| `salary_label` — Libellé salaire | texte salarial original | 33 % |55| `benefits` — Avantages | avantages sociaux publiés (JSON) | 0 % |56| `requirements` — Exigences | scolarité, expérience, langues (JSON) | 100 % |57| `date_posted` — Date de parution | ISO 8601 | 100 % |58| `date_deadline` — Date limite | date limite pour postuler | 0 % |59| `category` — Catégorie | taxonomie interne (TI, Santé, …) | 88 % |60| `language` — Langue | fr / en / bilingue (source ou heuristique) | 100 % |61| `company_logo` — Logo employeur | URL du logo si exposé par la source | 0 % |62| `apply_url` — Candidature | lien de candidature directe | 0 % |63| `gps` — GPS | lat/lng (géocodage sans invention) | 94 % |6465Exemple réel : *Manœuvre à la production – Quart de soir et de nuit* — Rougemont · 20,70$/h - 21,74 $/h · parue le 2026-09-21.6667## Fréquence & budgets6869- **Cadence** : resynchronisation **horaire** (PM2 `job-ka-sync` = `run.py watch 60`), suivie du géocodage en lot puis de la déduplication inter-sources.70- **Throttle** : 1.0 s minimum entre deux requêtes vers la source (`request_delay`).71- Cache BD des pages détail (`detail_cache`) : le détail d'une offre n'est re-téléchargé que si sa ligne de liste change.7273## Volumétrie & complétude live7475*(mesuré le 2026-09-21 18:06 EDT dans `data/jobka.db`)*7677- **Offres en base** : 46 (dont **33 actives**, 0 masquées comme doublons `dup_of`)78- **Salaire** : 11/33 actives (33 %)79- **GPS** : 31/33 actives (94 %)80- **Mode** : 2/33 actives (6 %)81- **Parution** : 33/33 actives (100 %)82- **Dernier sync** : 2026-09-21 17:20 — trouvées 33, +0, ~0, -083- **Syncs enregistrés** (`sync_log`) : 3348485## Erreurs & dépannage8687Erreurs relevées dans `sync_log` :8889| Erreur | Occurrences | Dernière fois |90|---|---|---|91| lassonde: page liste sans la section emplois (job-result-default) après 3 essais (HTTP 200… | 2 | 2026-09-14 08:17 |9293- Rejouer un sync isolé : `.venv/bin/python run.py sync lassonde` puis inspecter `sync_log` : `sqlite3 data/jobka.db "SELECT * FROM sync_log WHERE source='lassonde' ORDER BY ts DESC LIMIT 5;"`94- Garde-fous : une source qui retourne ≤ 25 % de sa médiane historique déclenche une alerte et les retraits sont suspendus ; une offre doit manquer 2 syncs consécutifs avant `active=0`.9596## Licence / conformité9798**Flux public du site carrières officiel de l'employeur** (API JSON de l'ATS ou HTML rendu serveur) — le même contenu que la page carrière affiche publiquement, prévu pour la diffusion des offres, sans authentification. Chaque offre conserve son URL originale et le bouton « Postuler chez Industries Lassonde » renvoie chez l'employeur. Aucune donnée personnelle de candidat n'est collectée. User-Agent identifié `JobKaBot/1.0 (+https://www.job-ka.com; contact@spboucher.ai)` sur les accès directs ; requêtes throttlées et plafonnées par budgets.99100## Historique101102**Mission connecteurs du 2026-08-18** — passage de 135 à 217 employeurs directs connectés, de 9 à 17 plateformes ATS, ajout de 3 portails agrégateurs et du canal de dépôt direct :103- `fd4bfc8` qualité lieux : rejet des villes hors Québec, bâtiments McGill → Montréal ;104- `5a66f48` +59 employeurs (sondage massif d'ATS + détection de pages carrières) ;105- `4917d57` 8 nouveaux ATS (Taleo, Njoyn, UltiPro, iCIMS, SuccessFactors, ADP WFN, Digital Recruiters, Workland) + 23 employeurs publics/parapublics ;106- `f6e7571` portails Guichet-Emplois, Jobillico, Espresso-Jobs — l'offre directe gagne toujours la canonique (dédup) ;107- `744cbfc` badge « Offre directe », stats directes/portails, dépôt direct employeurs ;108- `1604ff9` reprise sur coupure WAF Guichet-Emplois (retry + acquis partiel).109110Commits touchant `jobka/connectors/lassonde.py` :111112- `3758706` 2026-09-14 [ka6] fix connecteur lassonde: faux positif de supervision (épisode Sucuri transitoire) — repli Bright Data sur la page liste — le statut stale vient d'un unique échec à 08:17 (RuntimeError explicite de la garde du 2026-09-05 : 3× « HTTP 200 via scrapfly, 4515 octets » sans le conteneur job-result-default), combiné à la panne SQLite du matin (2b01fd4) qui avait empêché tout sync entre 05:32 et 08:17 — le connecteur est INTACT : rejeu = found=35, médiane exacte. Vraie faiblesse corrigée : pendant un épisode Sucuri, TOUTE la chaîne principale (direct→oxylabs→scrapfly) sert la même page tronquée « propre en apparence » (200 sans marqueur connu — 'access denied', 'sucuri_cloudproxy' etc. déjà couverts par is_blocked) à chaque essai, et le backoff 10-20 s ne suffit pas à sortir de l'épisode ; escalate() acceptait la réponse Scrapfly et ne tentait jamais Bright Data. La liste étant rendue serveur (render_js ne sert qu'au challenge), _fetch_list tente désormais Bright Data Web Unlocker (vendeur de déblocage différent) à chaque essai raté — vérifié live : BD livre 200/110 ko/35 cartes au moment même où le direct sert le challenge Sucuri 307. L'échec reste explicite (offres conservées) si BD échoue aussi. Test unitaire ajouté (repli BD gagnant, échec explicite si BD muet, BD jamais sollicité sur liste saine). Syncs rejoués post-patch : found=35 ok ×2. 104 tests pytest verts. pm2 restart job-ka-sync OK, site 200.113- `a3f3550` 2026-09-05 [ka6] fix connecteur lassonde: garde anti faux-zéro sur la page liste — le site (derrière Sucuri depuis 2026-08) sert parfois un 200 sans la section emplois ni marqueur de challenge connu (constaté 2026-09-05 21h09, sync à 0 alors que 32 offres réelles, is_blocked muet), le conteneur 'job-result-default' est maintenant exigé avec retry+backoff sinon erreur explicite dans sync_log; sync rejoué: 32 offres (médiane 32.0)114- `95df645` 2026-08-31 [ka6] fix connecteur lassonde: site passé derrière Sucuri Cloudproxy (challenge JS en 307 sans Location → 0 offre) — détection Sucuri dans is_blocked (_resilient) + fetch via get_resilient(render_js=True), 32 offres retrouvées115- `28057fe` 2026-08-19 lassonde : repli HTML pour la description (le site maison n'expose aucun JSON-LD JobPosting — corps de page après le h1, cache purgé et re-synchronisé : 31/31 offres décrites, 0 quarantaine)116- `86b0d0b` 2026-08-19 Famille Workland réécrite sur l'API JSON publique du frontal Atlas (jobs-prod published-external + default-profiles) : descriptions complètes fr/en, lieux géocodés, dates, mode de travail — 2 requêtes par cycle pour TOUT le réseau. Nouveau connecteur réseau atlas_workland (~80 employeurs QC : CSS scolaires, cégeps, CIUSSS Ouest-de-l'Île, Santé Québec Côte-Nord, ICM, STQ, UQTR, INRS… ; 1 238 offres QC). Connecteur cssdm retiré (couvert par le réseau), fixture remplacée par atlas_workland (sous-ensemble rejouable). Corrige la limite « workland description 0 % ».117- `4917d57` 2026-08-18 8 nouveaux ATS (Taleo, Njoyn, UltiPro, iCIMS, SuccessFactors, ADP WFN, Digital Recruiters, Workland) + 23 employeurs publics/parapublics et grands employeurs QC118