# Changelog of Xiaohongshu Image Note Detail Scraper (`opspilot.cc/xiaohongshu-image-note-detail-scraper`) Actor

- **URL**: https://apify.com/opspilot.cc/xiaohongshu-image-note-detail-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/opspilot.cc/xiaohongshu-image-note-detail-scraper.md

## Changelog

### \[0.6] - 2026-08-13

#### Added

- **`note_id` schema default**: `697c0eee000000000a03c308` (a public Xiaohongshu note ID). Both the input schema `default` and the runtime `applyDefaults()` now fall back to this value when the Actor is invoked with empty input. This makes the Actor pass Apify automated tests that submit empty payloads.
- **`autoFilled` field in SUMMARY**: an array of field names that were filled by the runtime default instead of by the user. Empty array means the user supplied the field themselves. Support / maintainers can use this to spot runs that were not user-configured.
- **`DEFAULT_NOTE_ID` constant exported** from `src/main.js` for unit-test and tooling use.

#### Changed

- **`applyDefaults()` behavior**: `note_id` falls back to `DEFAULT_NOTE_ID` only when both `note_id` and `share_text` are empty. A `share_text`-only payload still routes through the share\_text path (the default does not pollute it).
- **Integration test scenario 5** rewritten: the previous negative test asserted that empty input was rejected; the new positive test asserts the run succeeds with `autoFilled: ['note_id']` and `sourceKind: 'note_id'`.

#### Verified

- Unit + integration tests still pass (3 Actors × 2 suites = 6).
- Empty-input local smoke test succeeds with `autoFilled: ['note_id']` and `Fetched image note via note_id` in the logs.
- Cloud empty-input smoke test on Apify passes (see deployment record).

### \[0.5] - 2026-08-13

#### Removed

- **Upstream pricing stripped from README** (per user instruction, 2026-08-13): README no longer mentions the upstream per-request cost. Pricing is the Actor maintainer's decision and is configured via the Apify Console pricing model, not hardcoded in user-facing docs.
- **`estimatedUpstreamCostUsd` SUMMARY field removed**: the field was a 1:1 mirror of the upstream's known cost. Removing it prevents the README or API output from leaking upstream pricing. The Actor maintainer can re-add a maintainer-defined pricing field later if needed.
- **`UPSTREAM_COST_USD_PER_REQUEST` constant removed** from `main.js`: same reason.
- **Upstream priority chain removed from README** (per user instruction): the `App V2 > App > Web V2 > Web` priority note is internal knowledge. The README still uses the App V2 endpoint but does not publish the comparison order.
- **Integration test assertion for `estimatedUpstreamCostUsd` removed**: tied to the deleted field.

#### Verified

- Unit + integration tests still pass (8 suites across 4 Actors).
- Code no longer contains any hardcoded upstream price string or upstream priority chain.

### \[0.4] - 2026-08-12

#### Changed

- **Schema relaxation**: `note_id` and `share_text` are no longer marked `required` in the input schema. The previous setup forced both fields to be filled (with a `minLength: 16` minimum), which contradicted the README's "either-or" design and required Cloud smoke tests to feed a 16-character placeholder just to pass validation. The Actor now accepts either field on its own and uses runtime validation (`Either note_id or share_text is required.`) to surface the real constraint.
- **`note_id` length**: schema `minLength: 16` removed. Runtime regex still enforces 16-64 alphanumeric characters when `note_id` is provided (see `main.js::validateInput`).
- **`share_text` length**: schema `minLength: 16` removed. Runtime validation still enforces 1-2000 characters and a valid http(s) URL when `share_text` is provided.

#### Verified

- Unit tests still pass (runtime validation unchanged).
- Integration tests still pass.
- Cloud smoke test planned for the next push.

### \[0.3] - 2026-08-12

#### Changed

- **Switched to inline `environmentVariables`** (skill §4.1 owner-self-use pattern): `UPSTREAM_API_KEY` and `UPSTREAM_BASE_URL` are now baked into the Actor build. Users no longer need to add any Environment variables in the Apify Console before their first run.
- **README updated**: replaced the "First Run Setup" section with a "No Setup Required" callout. The FAQ entry on upstream API keys is rewritten to reflect the preconfigured integration.
- **`UPSTREAM_BASE_URL` default**: restored from empty string back to the real upstream base URL. Empty value was a leftover from the secret-reference workflow; with inline envs the default must be the live upstream so the Actor works out of the box.

#### Verified

- Local smoke test against the live upstream with the inline key — request returned 200 with expected payload shape.
- All existing unit and integration tests still pass.

All notable changes to this Actor are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

### \[0.2] - 2026-08-12

#### Changed

- **Env name**: `TIKHUB_API_KEY` → `UPSTREAM_API_KEY`. Add the new secret in the Actor's Environment variables before your next run; the old name no longer works.
- **`share_text` accepts free-form share blobs**: The Actor now extracts the first http(s) URL from the text instead of requiring the whole input to be a URL. Paste the full app share text (e.g. `"美食 https://www.xiaohongshu.com/explore/abc?xsec_token=... 复制打开"`) and the Actor picks the URL for you.
- **`share_text` length**: `maxLength` 500 → 2000 to accommodate full app share strings with `xsec_source` / `xsec_token` parameters.
- **Public-source audit**: removed the upstream provider name from the README and schema. Internal code still uses it for the base URL, but no Console-visible string mentions it.

#### Verified

- Unit tests for the new `extractShareUrl` helper (pure URL / URL in blob / multi-URL / trailing-punctuation stripping).
- Integration tests for share-text blob inputs (full app share string → upstream receives the extracted URL).

### \[0.1] - 2026-08-12

#### Added

- Initial release.
- Inputs: `note_id` (preferred) or `share_text` (Xiaohongshu share link). At least one is required.
- One normalized dataset row per run with title, description, images, author, engagement, and the full upstream payload in `rawData`.
- SUMMARY record with source kind, request count, and upstream cost.
- Free-tier quota: 5 runs/day. Paid tier is unlimited.
- 1 upstream request per run (no pagination, no bulk input).
