# Changelog of AliExpress Scraper for Dropshipping - Exact Sales & Prices (`badr_xba/aliexpress-scraper`) Actor

- **URL**: https://apify.com/badr_xba/aliexpress-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/badr_xba/aliexpress-scraper.md

## Changelog

### 2026-11-09 (review invitation)

- Successful runs that saved at least one result end their status message with one short, optional invitation to leave a Store review or open an issue (never on failed or empty runs); README section "Feedback and reviews". Output and billing unchanged.

### 2026-11-08 (visual kit 1.1.0)

#### Added

- `isNewShopperPrice` (new-shopper / Welcome Deal offer shown on the card) and `lowestPriceDays` ("Lowest price in
  N days" tag), read from the card's language-independent tag codes with the English text as fallback.
- Dataset view **Deals** (image, title, price, original price, discount, the two tags, Choice, free shipping, sold,
  rating, link) and its output-schema link.
- Visual report: kit 1.1.0 (at most 3 photos per product, main photo first, thumbnail strip on cards), live
  progress page while the run is going (searches done/total, products so far; at most one write a minute),
  data-quality panel, failed searches grouped by error code, coded warnings (filtered out, unrelated suggestions,
  budget). The report is also finalised when the run crashes unexpectedly (FAILED_INPUTS saved too).

### 2026-11-08

#### Added

- **Visual report** (`REPORT` record, Output tab → *Visual report*): product cards with photo gallery, price,
  original price, discount, rating, units sold, Choice/Ad badges, free shipping, ships-from and delivery days;
  compare mode (up to 4); key figures, price/discount/best-seller charts, search, filters, sorting, table view and
  CSV/JSON export of the filtered rows. Images are loaded with `referrerpolicy="no-referrer"` (AliExpress refuses
  hotlinked images that send a referrer). Built by the shared `src/visual_kit.py` (v1.0.1) with this Actor's
  `src/report.py`. At most 2,000 rows are kept in memory for it; it is never billed and a report error is only
  logged as a warning.
- Output schema: *Visual report* link; key-value store schema: `REPORT` (text/html).

#### Fixed

- Image links (`image`, `images`): `//host/…` becomes `https://host/…`; blank, `data:` and other non-http values
  are dropped (for `image`, the next real picture of the card is used), and the same picture is listed once.
  Valid links are unchanged.

#### Tests

- `tests/test_report.py`: 14 tests on the 20 real products of a production run (image ownership, gallery,
  placeholders, URL normalization in the parser, escaping, a 5,000-row synthetic set, export = embedded data,
  failure safety, REPORT saved as exactly text/html, rows pushed → report).

### 2026-11-07

#### Fixed

- `categoryId`, `postCategoryId`, `skuId`, `listedAt` and `priceFormatted` are always written as text (or null), as the dataset schema declares, even if AliExpress sends a number in its JSON.
- Text booleans sent by integrations (`"includeAds": "false"`, `"deduplicate": "0"`) are read correctly; before, any non-empty text meant `true`.

#### Improved

- Products are written to the dataset once per results page (one API call) instead of once per product. The limit and the maximum cost per run are checked under a lock in the same step, so parallel searches cannot overshoot them; a product listed twice on the same page is deduplicated.
- Retry pause is exponential (1.5 s, 3 s, 6 s, 12 s, capped at 20 s) with jitter, instead of linear.
- `startUrls` has an explicit empty default.
- Offline test suite (`python -m pytest -q`) with a real, trimmed search payload and two Apify datasets; tests are excluded from the Docker image.
