# Changelog of Vietnam Tenders & Contract Awards (muasamcong) (`a-g-d/vn-tenders`) Actor

- **URL**: https://apify.com/a-g-d/vn-tenders/changelog.md
- **Full Actor documentation**: https://apify.com/a-g-d/vn-tenders.md

## Changelog

All notable changes to this project are documented here. The format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project adheres to
[Semantic Versioning](https://semver.org/).

### \[0.2.2] - 2026-09-27

#### Changed

- The public Store page (README) no longer has a License section: the source is not published, and the data's terms are those of the source, described under "Data source".

### \[0.2.1] - 2026-09-26

#### Changed

- The README is now purely the public Apify Store page: build, test and schema notes moved
  to `DEVELOPMENT.md`, and field documentation points to the Store's Output tab instead of
  files in the (private) repository.
- The User-Agent's contact link is the public Store page (https://apify.com/a-g-d/vn-tenders) instead of the
  private repository.

### \[0.2.0] - 2026-09-26

#### Added

- Contract awards: input `recordType: "awards"` returns published contractor-selection
  results (KQLCNT) instead of tender notices, from the same search service with the
  portal's own result filters. `publishedSince` applies to the result's publication time
  (`awardPublicDate`); `openOnly` is ignored; every other filter applies as for notices.
- Award items carry the notice summary plus `resultId`, `awardPublicDate`, `decisionDate`,
  `outcome` (awarded, no\_winner, cancelled, result\_cancelled, result\_voided,
  result\_not\_recognised, suspended, or other with the raw `outcomeCode`), the portal's
  English `outcomeLabel`, `winnerNames`, `winnerCodes`, `jointVentureName`,
  `winningPrices`, a de-duplicated total `winningPrice` and `resultPetitionCount`.
  Online quotations (CGTTRG), which publish the winner in another index field, are covered.
- Award results (`includeDetail` on awards) from the result service: approval decision,
  contract type and period, package and estimated price, every lot with its bidders,
  winners, winning prices and reasons for not selecting the others, cancellation details
  and document names.
- Awards come newest result first: the index sorts by the notice's date only, so award
  windows are split until one page holds them and each page is sorted by result time. The
  10,000-hit window slicing applies to the result's publication time too.
- Pay-per-event events `award-result` (per stored award) and `award-detail` (per stored
  result detail), charged after storing like `tender-notice` and `tender-detail`.
- A `recordType` field (`notice` or `award`) on every item; the dataset schema is a union
  of the two item types (draft-07 `oneOf`, checked with Apify's validators), with a second
  dataset view "Awards" and a second output link.

#### Changed

- Notice details for `processApply` KHAC, ADB and WB now come from the service the
  portal's notice page uses for them (`lcnt_tbmt_ttc_vk_adb`), mapped into the same
  `detail` shape. On a live sample of 2026-09-26, 23 of 23 such notices got a detail,
  against none before.
- `detailUnavailableReason: "no_data_from_portal"` on notices now means an open simplified
  online quotation (CGTTRG), which has no public detail.
- The User-Agent reports version 0.2; the actor title and description mention awards.
- Internal: shared schema building blocks under `src/schema/`, one run loop for both
  record types, `pushItems`/`itemCostUsd` instead of `pushNotices`/`noticeCostUsd`.

### \[0.1.0] - 2026-09-25

#### Added

- Tender notices (TBMT) from Vietnam's national e-procurement portal
  (muasamcong.mpi.gov.vn) through its JSON search service, filtered by keyword, procurement
  field, province, open status and publication window, newest first, up to 10,000 per run.
- Publication windows that reach the search service's 10,000-hit cap are split in half
  (newer half first) until every part fits, so no notice is lost to the cap.
- Optional notice details (`includeDetail`) from the detail service verified for notices
  under the procurement law: procuring entity, project and plan, capital source, contract
  type and period, bid validity, guarantee, fee, package status, lots of multi-lot
  packages, the approval decision and attached file names and ids. Notices the service
  does not answer keep `detail: null` with a `detailUnavailableReason`.
- English labels for procurement field, selection method, procedure, legal process,
  notice status, package status and contract type, from the portal's own category lists
  (three mistranslated selection methods corrected). Unknown codes stay as codes.
- Province filter by code or by name in Vietnamese or English, with or without
  diacritics, matching both the 34 post-July-2025 provinces and the former ones.
- Every portal timestamp normalised to ISO-8601 in Vietnam time (`+07:00`), plus
  `fetchedAt` (UTC), `sourceUrl` and a link to the notice page per item.
- Pay-per-event billing: `tender-notice` per stored notice and `tender-detail` per stored
  detail, charged only after storing. Each page is planned against the remaining spending
  limit before any detail is fetched, and the run stops cleanly when the limit is used up.
- Retries with exponential backoff and jitter on connection errors, timeouts, 5xx and 429,
  within a per-request cap and a run-wide backoff budget. HTTP 400/401/403 and persistent
  `page: null` answers fail the run with a message that the portal may now require a
  verified reCAPTCHA token.
- Optional Apify Proxy (`proxyConfiguration`, off by default) and a traffic summary at the
  end of each run (response bytes per search page and per detail call).
- Dataset schema with per-field title, description and example and an "Overview" view,
  output schema, zod-validated input mirrored in the input schema, offline tests against
  real captures (including Apify's own schema validators and a real-SDK billing test),
  an opt-in live smoke test, CI and a pre-commit hook.
