All notable changes to this Actor are documented here.
- Full crawler implementation:
src/companyid.py (REQ-1/REQ-2 subdomain resolution),
src/models.py (ActorInput/ResultRow, ADR-0004), src/client.py
(RecruiteeClient — one curl-cffi GET per company against Recruitee's public
api/offers/ list endpoint, impersonate= rotated across
chrome131/chrome124/firefox147/safari17_5, exponential backoff 2s→30s cap over 5
attempts on 408/429/5xx/network errors honouring Retry-After, 404 → None
sentinel never retried — REQ-3/REQ-9/REQ-11), src/scraper.py (per-offer
normalization — REQ-4 description gate with zero second HTTP calls, REQ-5
"YYYY-MM-DD HH:MM:SS UTC" timestamp parsing, REQ-6 numeric-string salary
casting, REQ-7 boolean defaults, REQ-8 nullable-code normalization, REQ-10
client-side result cap, per-company CompanyOutcome tracking), and
src/main.py/src/__main__.py (SDK plumbing, batched Actor.push_data() +
Actor.charge() with no idempotency_key per REQ-13, REQ-12 status message
distinguishing all-failed / legitimate-all-zero / mixed outcomes).
- Test suite:
tests/test_companyid.py, tests/test_models.py,
tests/test_client.py, tests/test_scraper.py, tests/test_main.py — 111
tests, full REQ-1 through REQ-13 coverage including edge cases (malformed
timestamps, non-numeric salary, missing required offer fields, retry
exhaustion, mixed per-company success/failure).
- Added
tests/fixtures/auditdata_offers.json (representative multi-offer
fixture covering populated/null-salary/null-department/numeric-string-salary
variants) and promo.json (GTM manifest).
- Initial scaffold:
.actor/ config (actor.json, input_schema.json, dataset_schema.json, output_schema.json, pay_per_event.json, Dockerfile), pinned pyproject.toml, and QA fixture directory. Crawler logic not yet implemented.