Files
VacatureRadar/docs/architecture/SOURCE_ADAPTERS.md
T
2026-07-22 05:12:07 +02:00

7.3 KiB
Raw Blame History

Bron- en adapterarchitectuur

1. Adaptercontract

Iedere adapter implementeert conceptueel:

class SourceAdapter(Protocol):
    parser_key: str
    parser_version: str

    def extract(self, content: str, *, url: str) -> ExtractionResult: ...

ExtractionResult bevat:

  • jobs: list[ExtractedJob];
  • stabiele parser key/version;
  • confidence 0..1;
  • machine-/mensleesbare warnings.

Adapters:

  • doen geen netwerkrequests;
  • schrijven niet naar ORM;
  • voeren geen scoring of bronpolicy uit;
  • werken deterministisch op aangeleverde fixtures;
  • bewaren alleen beperkte raw payload voor debugging;
  • leveren evidence per belangrijk veld.

2. Parservolgorde

Voor HTML:

  1. JSON-LD JobPosting;
  2. gespecialiseerde adapter op expliciete source parser key;
  3. generieke HTML-fallback;
  4. geen vacature wanneer minimumvelden ontbreken.

Voor XML/feed:

  1. RSS/Atom;
  2. sitemapdiscovery (backlog);
  3. geen generieke HTMLparser.

Voor e-mail:

  1. MIME decode zonder attachments;
  2. linkextractie met unsubscribe/privacyfilter;
  3. bij een platformmailbox uitsluitend gelabelde HTTPS-links op het gekozen jobboarddomein aanvaarden;
  4. externe tracking-, account-, help-, privacy- en uitschrijflinks verwerpen;
  5. platformalias en provenance bewaren;
  6. oorspronkelijke werkgever proberen te resolveren in een aparte begrensde taak.

3. Minimumvelden

Een jobdraft is verwerkbaar wanneer minstens aanwezig:

  • titel;
  • HTTP(S)-URL of stabiele externe identiteit.

Employer, locatie en beschrijving mogen tijdelijk ontbreken, maar verlagen confidence. Een generieke pagina zonder herkenbare titel wordt niet als job opgeslagen.

4. Confidence

Richtwaarden:

Methode Baseline
JSON-LD geldig individueel JobPosting 0,95
gespecialiseerde publieke ATS-adapter 0,90
RSS/Atom 0,82
vacaturemailanchor 0,650,75
generieke HTMLselectors 0,450,75

Fieldconfidence en extractionconfidence zijn gescheiden. Een perfecte titel maakt een ontbrekende werkgever niet betrouwbaar.

5. Nieuwe adapter toevoegen

  1. Maak apps/sources/adapters/<naam>.py.
  2. Geef vaste parser key en semverachtige version.
  3. Parse alleen de aangeleverde content.
  4. Maak geanonimiseerde fixture onder fixtures/.
  5. Test happy path, ontbrekende velden, gewijzigd markup en malafide HTML.
  6. Registreer uitsluitend voor een expliciete source/parserdetectie.
  7. Documenteer bronbeleid, rate limit en canonical URL-gedrag.
  8. Voeg traceability toe.

6. ATS-strategie

Gespecialiseerde adapters mogen publieke HTML of publieke, documenteerbare endpoints gebruiken wanneer:

  • geen login/token nodig is;
  • bronpolicy allow is;
  • gebruiksvoorwaarden/robots zijn beoordeeld;
  • het endpoint rechtstreeks vacatures van de werkgever publiceert;
  • rate limiting en identifiers stabiel zijn;
  • fallback naar HTML mogelijk is.

Een endpoint mag technisch JSON zijn zonder een commerciële platform-API-integratie te vormen. De policybeslissing blijft per bron vereist.

7. Bronpromotie

candidate
  -> policy/robots/terms review
  -> trial (kleine frequentie, parserconfidence meten)
  -> active (voldoende succesvolle runs)
  -> quarantined (policy, security of herhaalde parsefout)
  -> trial/active na expliciet herstel

Automatische promotie naar active vereist minimaal:

  • meerdere succesvolle runs;
  • geen private/deny redirect;
  • voldoende extractieconfidence;
  • geen onverwachte volumepiek;
  • policy nog geldig.

Juridische voorwaarden mogen niet door een taalmodel als definitief toegestaan worden verklaard.

8. Rate limiting

Per eTLD+1/domein:

  • concurrency standaard 1;
  • minimum interval standaard 30 seconden;
  • respecteer Retry-After;
  • conditionele GET met ETag/Last-Modified;
  • exponentiële backoff bij fout;
  • geen retry op policyblokkade;
  • adaptieve lagere frequentie bij stabiele, zelden wijzigende bron.

9. Parserdrift

Bronhealth detecteert:

  • leeg resultaat waar eerder vacatures waren;
  • sterke daling in velddichtheid/confidence;
  • nieuwe foutstatus/contenttype;
  • wijziging in jobvolume;
  • ontbrekende title/URL;
  • veel nieuwe canonical keys door URLtrackingwijziging.

Automatisch herstel mag veilige selectorvarianten proberen, maar nieuwe logica moet eerst op opgeslagen fixture/snapshot draaien. Geen live agressieve exploratie.

Publieke ATS-providers (VR-106)

Provider Hostherkenning Parserbenadering Opmerking Rate limit (advies)
Greenhouse *.greenhouse.io, *.boards.greenhouse.io gespecialiseerd endpoint/JSON + detailstructuren gebruik alleen publieke boardpagina's/feeds, geen private/persoonlijke endpoints 15 requests/min met conditional request indien beschikbaar
Lever jobs.lever.co gespecialiseerd JSON/HTML listing+detail alleen publieke postings, geen recruiter login flow 60 requests/min per domein
Recruitee *.recruitee.com gespecialiseerd listing+detail parser parse alleen door werkgever geïntendeerde publieke vacature-URLs 60 requests/min per domein
SmartRecruiters *.smartrecruiters.com gespecialiseerd listing+detail parser geen interne API-auth nodig; stop bij CAPTCHA/anti-bot 30 requests/min per domein
Workable apply.workable.com gespecialiseerd listing+detail parser alleen publieke vacaturepagina/JSON; geen private endpoints 30 requests/min per domein

Gedeelde ATS-hosts zijn geen bronidentiteit: meerdere werkgevers mogen hetzelfde providerdomein gebruiken zolang iedere bron een unieke publieke base_url heeft. De scheduler blijft per origin coördineren, zodat deze extra bronrecords de providerlimiet niet omzeilen.

Voor Corda Campus is een begrensde regionale listingadapter beschikbaar. Die leest uitsluitend de expliciete /jobs/-kaarten, bewaart de vermelde werkgever en weigert iedere joblink buiten cordacampus.com. Vacaturedetail en sollicitatie-URL's worden niet automatisch gevolgd.

Voor elke provider-adapter:

  • supports() kijkt eerst op host/marker om andere pagina's niet te matchen;
  • listingpayloads produceren kandidaten zonder fetch van detail;
  • detailpayloads vullen een enkele vacaturestructuur;
  • elke veldafklaring krijgt veld-evidence met method-labels en confidence.

Regionale Mol-adapter (VR-126)

MolRegionEmployerAdapter verwerkt uitsluitend vijf vooraf gereviewde HTTPS-lijstroutes rond postcode 2400: SCK CEN, Cipal Schaubroeck, VanRoey, NTX/Netropolix en Thomas More. De adapter doet geen netwerkrequests en accepteert alleen same-host vacaturelinks. Cipal, NTX en Thomas More vereisen een expliciete lokale marker; bij Thomas More wordt bovendien de vaste publieke werkgever-GUID gecontroleerd. VanRoey-detailpaden zijn door robots uitgesloten en worden daarom nooit door VacatureRadar gefetcht; alleen de toegestane overzichtspagina dient als bron.

Kempen-werkgeversadapter (VR-201)

KempenEmployerAdapter voegt zeven gereviewde werkgeversroutes toe voor Ziekenhuis Geel, lokaal bestuur Geel, Stad Turnhout, Group Renotec, Ravago, Sanofi en DAF Trucks Westerlo. Iedere route heeft een vaste HTTPS-host en een toegestaan lijstpad; vacaturelinks moeten same-host zijn. Voor gedeelde of landelijke lijsten blijft alleen een kaart met de expliciete gereviewde vestiging over. Gemeente Mol wordt via de officiële same-host RSS-feed verwerkt. Interessante werkgevers zonder stabiele fail-closed parser blijven als niet-scanbare waaklijstbron zichtbaar.