fix(jobs): treat isRemote as 100% remote only; tighten cron for Canada QA

Reject hybrid or partial-office postings at ingest so the Remote badge and
filters match fully remote roles. Cron can PATCH search geography, remote-only
workplace types, and QA search terms before each scheduled pipeline run.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-16 15:53:55 -04:00
co-authored by Cursor
parent f5179304c1
commit 2e44a131e1
9 changed files with 286 additions and 65 deletions
+8 -2
View File
@@ -10,8 +10,14 @@ JOBOPS_URL="http://127.0.0.1:3005"
# JOB_TELEGRAM_MAX_JOBS=25
# Optional: override POST /api/pipeline/run sources (comma-separated). If unset, the server default applies.
# Example (matches typical JobSpy bundle + UK sources):
# JOBBER_PIPELINE_SOURCES=gradcracker,indeed,linkedin,glassdoor,ukvisajobs
# Canada + QA automation + fully remote (see JOBBER_CRON_* below):
# JOBBER_PIPELINE_SOURCES=linkedin,indeed,glassdoor,qajobsboard,arcdev,eluta,bctenet
# Optional: applied via PATCH /api/settings immediately before each scheduled run (ilia profile when BASIC_AUTH_USER=ilia).
# JOBBER_CRON_SEARCH_CITIES=Canada
# JOBBER_CRON_JOBSPY_COUNTRY=Canada
# JOBBER_CRON_WORKPLACE_TYPES=remote
# JOBBER_CRON_SEARCH_TERMS=QA Automation Engineer|SDET|Software Development Engineer in Test|Automation Test Engineer
# Optional — only if BASIC_AUTH_USER / BASIC_AUTH_PASSWORD are set in Jobber .env (use one pair; cron runs as a single identity)
# BASIC_AUTH_USER=""
+31
View File
@@ -44,6 +44,35 @@ fetch_status() {
"${BASE}/api/pipeline/status"
}
apply_cron_settings() {
local patch='{}'
if [[ -n "${JOBBER_CRON_SEARCH_CITIES:-}" ]]; then
patch="$(echo "$patch" | jq --arg v "$JOBBER_CRON_SEARCH_CITIES" '. + {searchCities: $v}')"
fi
if [[ -n "${JOBBER_CRON_JOBSPY_COUNTRY:-}" ]]; then
patch="$(echo "$patch" | jq --arg v "$JOBBER_CRON_JOBSPY_COUNTRY" '. + {jobspyCountryIndeed: $v}')"
fi
if [[ -n "${JOBBER_CRON_WORKPLACE_TYPES:-}" ]]; then
patch="$(echo "$patch" | jq --arg v "$JOBBER_CRON_WORKPLACE_TYPES" \
'. + {workplaceTypes: ($v | split(",") | map(gsub("^\\s+|\\s+$";"")) | map(select(. != "")))}')"
fi
if [[ -n "${JOBBER_CRON_SEARCH_TERMS:-}" ]]; then
patch="$(echo "$patch" | jq --arg v "$JOBBER_CRON_SEARCH_TERMS" \
'. + {searchTerms: ($v | split("|") | map(gsub("^\\s+|\\s+$";"")) | map(select(. != "")))}')"
fi
if [[ "$patch" == "{}" ]]; then
return 0
fi
local resp
resp="$(curl -sS --compressed "${AUTH[@]}" -X PATCH "${BASE}/api/settings" \
-H "Accept: application/json" -H "Content-Type: application/json" \
-d "$patch")"
if ! echo "$resp" | jq -e '.ok == true' >/dev/null 2>&1; then
send_tg_html "Jobber: PATCH /api/settings failed before cron run: $(tg_html_escape "$(echo "$resp" | jq -c . 2>/dev/null || echo "$resp")")"
exit 1
fi
}
fetch_jobs_list() {
curl -sS --compressed "${AUTH[@]}" -H "Accept: application/json" \
"${BASE}/api/jobs?view=list"
@@ -164,6 +193,8 @@ if echo "$body" | jq -e '.data.isRunning == true' >/dev/null 2>&1; then
exit 0
fi
apply_cron_settings
# Optional: comma-separated sources (see JOBBER_PIPELINE_SOURCES in jobber-cron.env.example).
# If unset, POST body is {} and the server uses its default source list.
run_body='{}'