Gigflow docs
Engineering

ADR-0011: Vacancy geocode stage

Geocode vacancy locations in one fixed flow stage instead of enrichment children.

Status: Proposed. Implementation available for review.

Date: 2026-09-23

Context

ADR-0007 keeps an enrich stage that adds one geocode child per location and one recruiter-match child per contact, waits for them, and combines their results. A failed child does not fail the vacancy: its slot stays empty and enrich records the failure. Recruiter-match only returns a stub. The enrich stage needs an input mapper for several child results and reads error codes back from failed-job messages.

Decision

This ADR replaces the enrich stage and its optional children in ADR-0007 and ADR-0010. The vacancy ingestion sequence is:

harvest -> classify -> geocode -> embed -> finalize

The geocode job receives the classify result. It geocodes each classified location in order through GeoClient with the location layers, and adds geocodedLocations with one slot per location. A location without a match, or with a match that has no country, keeps its slot as null. A job listing or a closed job detail is not geocoded. The processor owns these rules; the @gigflow/geo package owns the Pelias client.

A geocoding provider failure retries the geocode job. When all attempts fail, the vacancy flow fails. The vacancy is not stored without its locations. The next harvest submits the source again.

The classify result field preprocess.markdown becomes markdown.

Consequences

The vacancy-enrich and vacancy-recruiter-match queues, job contracts, and workers are removed. Flows published with the old graph wait for an enrich job that no worker runs. Each keeps an admission slot, because the scheduler frees a slot only when the flow root completes or fails. Drain both queues before deployment, or cancel those ingestions afterwards with VacancyClient.cancelIngestion, which removes the flow and frees the slot. Do not delete their jobs directly: a request whose flow root was deleted keeps its slot.

A Pelias outage that outlasts the retries now stops vacancies instead of storing them without coordinates. Recruiter matching is not part of the pipeline until a stage needs it.

Verification

From the repository root, with local Redis from dev/cli/dev up engine, run:

bun --env-file=apps/engine/apps/workers/vacancy/geocode/.env \
  test --timeout 30000 apps/engine/apps/workers/vacancy/geocode/e2e

The test runs the real worker against a local Pelias fixture. The report is written to .context/verification/vacancy-geocode/geocode-stage/report.json.

On this page