# Changelog of TED Tenders: Romania & EU notices by CPV (official API) (`clearsource/ted-tenders`) Actor

- **URL**: https://apify.com/clearsource/ted-tenders/changelog.md
- **Full Actor documentation**: https://apify.com/clearsource/ted-tenders.md

## Changelog

### 0.1.5 — 2026-10-04 (unpublished)

- NEW-T1 (QA re-verification): a run counts as complete (watermark may advance) only if the last page was fully processed; a page cut short by `maxResults` no longer counts as complete even when TED returns no iteration token. Golden test: one page, 3 notices (2026-10-03, 09-30, 09-28), null token, `maxResults: 1`, three incremental runs → each notice emitted exactly once.
- `scripts/check-shared.mjs` + `npm run check-shared`: `src/core` must be byte-identical across `actors/*/src/core` (exit 1 on a differing or missing file).

### 0.1.4 — 2026-10-04 (unpublished)

- TED-SEC-08 (re-verification): health mode now needs the maintainer token, same rule as `actors/ro-company-status`: `PDA_HEALTH_ENABLED=1` + secret input `healthToken` equal (constant time) to the secret env `PDA_HEALTH_TOKEN` (≥ 32 chars, `@pdaHealthToken` in `.actor/actor.json`) + optional `PDA_MAINTAINER_USER_ID` = `APIFY_USER_ID`. `healthToken` is a hidden secret input field and is excluded from the state key.
- `npm run monitor` reads `PDA_HEALTH_TOKEN` from the local environment, refuses without it and deletes the temporary `INPUT.json` after the run.

### 0.1.3 — 2026-10-04 (unpublished)

- Provenance envelope 1.1.0 vendored (additive: `personal_data` adds `minimised`, `envelope_version` accepts `1.1.0`); output schema `ted-tenders/notice` 1.1.0 references it; shared `src/core/provenance.ts` updated (identical in all actors); `.actor/dataset_schema.json` regenerated. Emitted records unchanged (`envelope_version` `1.0.0`, `personal_data` `none`).
- QA-3 closed: User-Agent `public-data-api/ted-tenders@0.1.3 (+https://ppftec.com)` (operator PPFTEC S.R.L., DECISIONS D3 provisional); fixture recorder uses the same contact.
- First live contract test (3 requests, 2026-10-04T11:31:57Z): all fail-level checks green; p50 220 ms, p95 720 ms. Report: `docs/qa/ted-tenders-live-2026-10-04.md`.
- `docSha256` pinned to `e0cfe4e8…2ff8` (`api-v3.yaml`, 1,830 `fields` enum values, all 18 of ours present).
- CPV hierarchy answered (1 extra live request, `scripts/probe-cpv.mjs`): `classification-cpv IN (72000000)` matches child codes; documented in README Limits.
- Live contract test now logs every request (method, URL, User-Agent, start time, status, latency, size) to `test/contract/out/`.

### 0.1.2 — 2026-10-04 (unpublished)

- Source approved: `TED_SOURCE.allowListStatus = 'approved'` (Petre, 2026-10-04, DECISIONS D1, TED only). The gate code and its tests stay; tests inject a pending status through `RunDeps.sourceStatus`.
- TED-SEC-07: relative dates are bounded (max 50 years) and every resolved date must lie in \[1993-01-01, today + 2 years]; `"999999 years"` is now an input error instead of a crash.
- TED-SEC-08: `mode: "health"` requires `PDA_HEALTH_ENABLED=1` (set by `npm run monitor` and the maintainer's schedule); otherwise invalid input, no request.
- TED-SEC-06: caps of 20 keywords, 100 CPV codes, 40 countries, 2,000-character `expertQuery` (also in `.actor/input_schema.json` as `maxItems`/`maxLength`); keywords limited to plain words, no `AND/OR/NOT` or operators.
- Security-review observation: `notice_url`/`xml_url` must be on `ted.europa.eu`, otherwise drift.
- Dependencies: `http-cache-semantics` 4.3.0 (fixed release published 2026-10-04) via `npm audit fix` (no `--force`); `npm audit` now reports 0 vulnerabilities; accepted-risk note removed from the README.
- README: "Daily Romanian tenders above the EU threshold" example (D7-B, daily TED-RO).
- Live calls stay off until the User-Agent has a contact URL (QA-3): `test:contract` skips and `scripts/record-fixtures.mjs` refuses until then.

### 0.1.1 — 2026-10-04 (unpublished)

Fix round for `docs/qa/report-ted-tenders-2026-10-04.md` and `docs/security/ted-tenders-review-2026-10-04.md`.

- QA-1: incremental watermark advances only when a run processed its whole result set; early stops re-scan the same window next time, and `seen` is pruned only below the query window (no skipped or re-charged notices).
- QA-2: `Retry-After` honoured in full (120 s cap removed); a wait beyond the run time budget aborts with exit 1 and a clear message.
- QA-4: the pending-source gate also refuses local live runs (`main`, `monitor`, `test:contract`) unless `PDA_ALLOW_PENDING_SOURCES=1`; dry runs and recorded-fixture runs still work offline.
- QA-5: kill switch re-checked before every request and retry.
- QA-6: redirects are never followed (`redirect: 'manual'`, 3xx fails without retry) and the response host is checked.
- QA-7: health doc check uses membership in the OpenAPI `fields` enum (new dependency `yaml`), not a substring match.
- TED-SEC-01: `incremental` + `expertQuery` rejected as invalid input.
- TED-SEC-02: per-run caps on scanned notices (`max(10 × maxResults, 2,000)`) and pages; 4-hour run time budget (also bounded by `ACTOR_TIMEOUT_AT`); `defaultRunOptions.timeoutSecs` 14,400 in `.actor/actor.json`.
- TED-SEC-03/09: base image `apify/actor-node:24` pinned by digest, `USER myuser`, `npm ci --ignore-scripts` in the runtime stage, `.dockerignore` excludes `.env*`, `.git`, `docs`; `engines.node` `>=22`, `@types/node` 22.
- TED-SEC-05/10: `basic-ftp` overridden to 6.2.1; `.npmrc` (`legacy-peer-deps`) deleted; `http-cache-semantics` recorded as accepted risk in the README.
- Tests: `test/e2e/fixes.test.ts` (21 cases); `test/qa` passes.

### 0.1.0 — 2026-10-04 (unpublished)

- First build per `docs/spec/actors-wave1.md` section 2: TED Search API v3 search with ITERATION paging, 18 fixed fields, mapping to `ted-notice` 1.0.0 with provenance envelope 1.0.0.
- Kill switch, allow-list gate (source pending D1), dry run, incremental state, drift detection with `DRIFT_REPORT`, health mode.
- Politeness per `docs/compliance/sources.md` row e: 1 request/s, at most 500 notices per 6 minutes.
