# Changelog of SEEK, JobStreet & JobsDB Job Scraper — 8 Markets (`bluedata/seek-jobstreet-jobsdb-scraper`) Actor

- **URL**: https://apify.com/bluedata/seek-jobstreet-jobsdb-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/bluedata/seek-jobstreet-jobsdb-scraper.md

## Changelog

This changelog describes customer-visible behavior only. Development-only
materials are not included.

### Unreleased — Launch readiness

- New `coverageMode` input. `best_effort` (default) keeps the existing bounded
  scan. `fill_target` widens the page and detail-candidate windows and keeps
  scanning and enriching until `maxResults` matched jobs are emitted, the source
  is exhausted, or a hard run limit is reached. Runs now report `coverageMode`,
  `requestedResults`, `targetReached`, `shortfall`, `candidatesScanned`,
  `candidatesRejected`, a run-level `stopReason`, and a short `resultNotice`;
  `fill_target` runs that cannot meet the target add a `TARGET_NOT_REACHED`
  warning. Pricing events are unchanged; more scanning does not create extra
  charged events.
- Actor title and description are updated for the 8-market launch, including
  advertised export formats, optional company data, and RUN_SUMMARY coverage.
- Input and output documentation now states that parsed queries are forwarded
  exactly without translation or synonym substitution. Location aliases retain
  original and effective values; no geographic expansion is claimed.
- Removed the two automatic MY/ID query substitutions. Original parsed query
  text is used for both generated searches and URL-derived targets.
- Pricing documentation distinguishes dataset-item events, start events, and
  optional enrichment work. No new billing event is introduced.

### Unreleased — Verified multilingual relevance and multi-query accounting

- Bounded runs fetch scan-sized source pages (minimum 100 listings) instead of
  shrinking the page to `maxResults`. Filters run after fetching, so the old
  behavior made filtered markets stop at the candidate window with fewer results
  than requested. HK searches now get a wider candidate window within the same
  page-count safety cap.
- `resultLimitReached` (final output reached the requested cap) and
  `coverageLimitReached` (source fetch window capped) are reported independently
  on the run summary and on each search. The legacy `limitReached` field remains
  available as a broader cap signal; use the two explicit fields to distinguish
  output limits from incomplete source coverage.
- Incremental runs report `baselineComplete` and `expiredRecordsReliable`. A
  coverage-limited baseline suppresses `emitExpired` markers entirely and adds
  the `BASELINE_INCOMPLETE` warning; missing jobs beyond the fetch window are no
  longer mistaken for expired postings. Searches always expose
  `coverageComplete` as an explicit boolean, never null.
- Detail enrichment candidates scale with the output cap (5x, minimum 25) so
  detail-dependent filters can refill the requested results instead of stopping
  after a few rejected candidates.
- `searchPlan` and `searches` expose `originalLocation` (caller input) and
  `effectiveLocation` (source label) separately, e.g. `香港` vs `Hong Kong`.
  Original query text remains unchanged; there is no translation.
- Named incremental baselines use a cloud KVS created on first use. State
  failures are surfaced and no longer silently classify every row as new.
- State-key labels are hashed into Apify-safe record keys, including when the
  caller's label contains punctuation that Apify KVS does not allow.
- Search status is separated from detail enrichment status. A completed search
  stays `sourceStatus: ok` when detail requests are partial; `detailsEnriched`
  counts successful detail responses per candidate listing.
- Coverage-limited searches expose `coverageLimit`, `coverageLimitedSearches`,
  and `sourceStatus: coverage_limited`; they are not presented as Actor failures.
- Thai queries in TH and Chinese queries in HK use exact query text without
  translation or added synonyms. Complete no-match coverage returns `no_results`;
  capped searches return `coverage_limited`.
- Zero-evidence source suggestions are filtered before output; emitted records
  always have target-specific literal evidence and `relevanceScore: 1`.
- Non-Latin queries require literal evidence. Complete evidence-free targets
  expose `queryLanguage`, `languageSupport: unsupported`, and
  `rejectionReason: No verified query-term match`. For SG, Arabic/Korean targets
  with no first-page literal match terminate as unsupported instead of scanning
  generic fallback pages; literal matches remain eligible.
- `processedSearches`, `completedSearches`, and `fullyCoveredSearches` distinguish
  executed targets, terminal outcomes, and exhaustive source coverage. Coverage
  caps count as completed terminal outcomes while remaining not fully covered.
- Source request/time and challenge failures remain partial; detail enrichment
  has its own `detailStatus`.
- Added per-target execution plans and attempted, processed, fully covered,
  skipped, discarded and resumed accounting. Unattempted work no longer counts
  as completed; speculative requests remain visible even when discarded.
- Multi-query and multi-URL runs divide the source candidate allowance across
  targets so a run-wide output cap does not silently prevent later targets from
  executing. The final emitted dataset remains capped.
- `searchPlan` now exposes each target URL and input source, making hidden
  default-query and duplicate URL cases observable.
- Arabic-script queries require literal evidence; unrelated source suggestions
  are filtered and an evidence-free target is reported as unsupported.
- The SG/HK fast path is limited to Arabic, Hangul and Chinese first pages with
  no literal evidence; literal matches remain eligible and no request budget is
  overridden. Thai queries in TH remain untranslated.

### Unreleased — Input and result-quality hardening

- Fixed TH Bangkok alias matching across case, whitespace and compound source
  labels; added HK Hong Kong/香港 label aliases without widening district filters.
- Corrected mixed-type input fields to use Apify's JSON editor. Query accepts
  text, native arrays or `{terms: [...]}`; start URLs accept strings or objects.
- Added opt-in `queryMatchMode` (`all_terms`/`phrase`) and literal match evidence.
  Field-only keyword flags validate the main query when no explicit include or
  exclude terms are supplied. Legacy keyword scopes remain available.
- Added two explicit MY/ID query phrase aliases, preserving original/normalized
  queries and checking literal evidence instead of accepting generic suggestions.
  This is not general translation or language detection.
- Source-ranked results without full literal evidence now carry explicit
  relevance warnings; source success is not semantic relevance certification.
- Added suspicious salary heuristics with null numeric bounds, readable source
  text and warning flags; foreign currency alone does not invalidate salary.
- Empty completed/filtered searches no longer fail record contract checking.
  Partial runs expose warning flags, filter counters and safe stage/code logs.
- Query-validation mode changes reset the incremental baseline. This does not
  establish concurrent-monitor safety or any live source-coverage guarantee.

### Unreleased — Optional data groups

- Detail concurrency is managed automatically at a default of 8 parallel detail
  requests; it is not a user-facing tuning input. The request budget still
  governs total detail work.

- Detail enrichment now runs as a continuous worker pool instead of batches,
  which shortens enriched runs at the same request budget.

- While one search's details are enriched, the next query's search page is
  fetched concurrently; if the run stops early, the scouted search's records
  are rolled back so results match a sequential run.

- Avoid unnecessary extra detail enrichment when no keyword filter is configured.

- Accept both single-object and list-shaped location hierarchies.

- Clarified that result limits do not cap network requests or spending.

- Added first-use `preset` choices: `basic`, `company`, and `full`; each keeps
  contacts and login-only applicant insights off by default.

- Clarified flattened CSV/Excel columns, persistent monitoring configuration,
  filter semantics, source URL inputs, and the 10,000-result output ceiling.

- Added individually selectable public listing and company-data groups; all are
  disabled by default and report availability when requested.

- Public contact fields require explicit opt-in and a separate notification
  allowlist. Data requiring a logged-in session remains unavailable.

- Added summary-level search suggestions and clearer partial-coverage status.

- Optional groups report `available`, `not_provided`, `restricted`, `failed`, or
  `skipped_budget` status instead of implying that every selected field exists.

- Nested optional data remains lossless in JSON; CSV/Excel exports should be
  treated as serialized cell values for nested arrays and objects.

- Added opt-in stateless `exportExcel` delivery for `JOBS.xlsx` (1–1000
  `maxResults`) with readable field/part rows and an exact Canonical JSON sheet;
  native Dataset exports remain unchanged.

### 0.1.14 — Result delivery and validation improvements

- Improved output handling for larger result sets.
- Strengthened input validation and partial-run status reporting.
- Improved handling of incomplete or malformed source records.
- Improved salary, posting-date, source labeling, and text normalization.
- Preserved optional detail enrichment, incremental flags, notifications, and
  compact output.

### 0.1.11 — Run safety and filter correctness

- Added clearer stop reasons and coverage status for incomplete searches.
- Improved result-limit behavior after final filtering.
- Improved checkpoint and retry behavior for interrupted runs.
- Added safer monitoring, notification, and incremental-state handling.

### 0.1.10 — Record handling

- A malformed listing no longer causes an entire result page to be discarded.

### 0.1.9 — Larger result limits

- Increased the supported maximum result limit to 10,000.
- Added run notes when numeric inputs are clamped.

### 0.1.8 — Filtering and notifications

- Improved notification failure reporting.
- Improved salary text handling for local currencies.
- Improved description keyword filtering when detail fields are enabled.
- Improved numeric filter validation.

### 0.1.7 — Persistent incremental state

- Added named state-store support for cross-run monitoring.

### 0.1.6 — Filters and notifications

- Added salary, date, classification, keyword, custom-field, and sort filters.
- Added incremental monitoring flags and optional notifications.
- Added compact and empty-field output controls.

### 0.1.5 — Enrichment and monitoring

- Added optional detail fields, classification filters, and incremental change
  flags.
- Improved retry and source-availability handling.

### 0.1.4 — Multi-market output

- Added normalized output across the supported APAC markets.
- Added market-aware currency, locale, and source metadata.
- Improved placeholder salary detection and text cleanup.

### 0.1.0 — Initial release

- Added structured public job-search results with salary, posting-date,
  category, location, and source-link fields.
