Shopify Promotion Rollback Review
Pricing
Pay per event
Shopify Promotion Rollback Review
Compare before, applied, and current Shopify CSV prices to identify variants requiring rollback review.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Kagerou AP
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
9 days ago
Last modified
Categories
Share
Review the main variant price after a Shopify promotion using three CSV snapshots: baseline before the promotion, applied after the promotion, and current now. The report identifies exact variants whose current price still matches the applied promotion, and separates intervening changes, variants already at baseline, unchanged promotions, and unknown or ambiguous records.
This is for Shopify CSV bulk-price agencies that already retain all three snapshots. If baseline or applied files were not retained, do not reconstruct them from guessed discounts. This Actor compares supplied CSV text locally. It does not fetch files, call Shopify, change a store, produce an import-ready patch, or determine that a restoration is safe or approved.
Try the original demo
The default input and API example are:
{"mode":"demo"}
Demo uses the project's original synthetic fixture in USD and has no custom report event. Leave all CSV fields omitted; supplied CSV data is rejected in demo. The fixture contains four exact variants with these expected outcomes:
| Variant | Baseline | Applied | Current | Review result |
|---|---|---|---|---|
| project-shirt / Size S | 20.00 | 15.00 | 15.0 | restore_candidate; review suggestion 20.00 |
| project-shirt / Size M | 20.00 | 15.00 | 17.00 | intervening_change |
| project-shirt / Size L | 20.00 | 15.00 | 20.00 | already_baseline |
| project-tote / Title Default Title | 9.00 | 9.00 | 9.00 | no_promotion_delta |
The automatic platform startup fee is disclosed below and also applies to demo.
Review your own snapshots
Use mode: "review", a single shop currency label, rightsConfirmed: true, and three nonempty CSV strings: baselineCsv, appliedCsv, and currentCsv. Review rejects missing or false rights confirmation. The currency label starts with a letter and contains at most 16 letters, digits, spaces, underscores, or hyphens. By confirming, you acknowledge authorization to upload and process all three snapshots in your Apify storage.
sample-review-input.json uses the same original synthetic fixture in charged review mode. It is separate from sample-input.json, which is the default demo. The currency label is supplied by you; the Actor does not verify it or perform currency conversion. Data is processed in the run and persisted to your Apify storage.
Supported CSV fields
| Purpose | Frozen supported headers |
|---|---|
| Product handle | Handle or URL handle |
| Main variant price | Variant Price or Price |
| First option | Option1 Name / Option1 name, Option1 Value / Option1 value |
| Second option | Option2 Name / Option2 name, Option2 Value / Option2 value |
| Third option | Option3 Name / Option3 name, Option3 Value / Option3 value |
The spaced option headers cover the legacy and current Shopify forms. Option1 value is required, including Default Title for a default variant. Repeated required headers are rejected; conflicting values in duplicate alias columns are rejected. Parsing handles RFC 4180 quoting, preserves string identifiers and leading zeros, and does not infer an identity from SKU.
Identity is the exact handle plus the complete option name/value tuple. Handle continuation is propagated only within the same product group. Image-only continuation rows are explicitly ignored and counted. Duplicate identities in any snapshot are ambiguous. An identity missing from any snapshot is unknown with missing_snapshot; no price restoration is guessed.
Prices must be nonnegative decimal strings with at most 12 integer and 6 fractional digits. Exponents, thousands separators, negative values, blank prices, and invalid money do not become usable prices. Comparison uses scaled integer arithmetic, so 15.0 and 15.00 compare equally without binary floating point. Invalid money produces unknown coverage.
Rules and human review
For an exact identity with valid prices in all three snapshots:
| Condition | Status |
|---|---|
| Baseline equals applied | no_promotion_delta |
| Baseline differs from applied; current equals baseline | already_baseline |
| Baseline differs from applied; current equals applied | restore_candidate |
| Current differs from both applied and baseline | intervening_change |
Only restore_candidate includes reviewTargetPrice, using the baseline's original price string. This is a review suggestion. Source rows and current conditions still require buyer review before any action. Missing, ambiguous, or invalid comparisons cannot produce a restore suggestion.
Outputs
Every completed run publishes one nonempty default Dataset summary with schemaVersion, rulesVersion, status, mode, currency, counts, coverage, limits, billing, reportKey, and reviewCsvKey. Dataset rows do not contain variant details.
The default key-value store holds:
- REPORT.json: complete JSON report and every union identity within the limit, with exact
handleandoptions,sourceRows { baseline, applied, current },prices { baseline, applied, current },status,reasonCode, and a review-onlyreviewTargetPricefor restore candidates. - REVIEW.csv: the same complete review facts in CSV form. Exported cells are guarded against spreadsheet formula execution. This CSV is intended for review and is not an import-ready Shopify patch.
The Actor Output schema links both reports and the summary Dataset. Counts explicitly include useful comparisons, missing snapshots, ambiguous records, invalid prices, and ignored rows; coverage identifies partial reviews. Output is complete for accepted inputs, with an explicit total and detail limit. The Actor rejects input above the union identity cap rather than silently truncating a paid report.
sourceRows records the physical end line of each parsed CSV record, including the header in line numbering. A quoted multiline record therefore points to its final physical line. The single Dataset summary is published before the custom event, so its billing may remain pending. REPORT.json is authoritative for the settled billing state; its later confirmed or ambiguous state does not create a second Dataset summary.
Limits and pricing
Each CSV has a hard limit of 5,000 data rows, 5 MiB UTF-8, and 200 columns. The union of exact identities across the three snapshots is capped at 5,000; the JSON and CSV reports contain all accepted identities. Only the main variant price is compared.
The custom event rollback_review_completed costs $0.50 for one delivered useful custom report, irrespective of variant count. A partial report with at least one useful exact comparison is one report event. Invalid input, all-unknown or all-ambiguous diagnostics, and the original demo incur zero custom report events.
The platform-managed apify-actor-start event is $0.00005 per start. There is no Dataset item event. The Actor does not manually charge the start event. Allow $0.50005 for a useful custom report including startup; the run's pricing and platform billing remain visible in Apify.
Funded useful capacity is determined before useful Dataset, KVS, or checkpoint content is published. The custom event is issued only after the complete JSON report, complete CSV report, and summary have been saved. An insufficient budget yields diagnostics without a useful paid report. Failed output persistence does not produce a report event. Resume state prevents a duplicate fee; an uncertain earlier charge fails closed without blind retries. Inspect billing for the observed event state.
Source and license
Runtime dependencies are pinned to Apify SDK 3.7.2 and csv-parse 6.1.0 in the package and lockfile. CSV parsing uses csv-parse under the MIT license; the license text is included in evidence/csv-parse-license.txt, copied from the project's inspected package license evidence.
The original synthetic demo fixture was created for this project and is made available under CC0 1.0. It contains no customer data. No WooCommerce PHP code or upstream Actor code is copied.
Local development
Install from the committed lockfile with npm ci, then run npm start. Before importing the SDK for local testing, set CRAWLEE_STORAGE_DIR in the child process environment to a product-specific isolated directory and confirm the SDK uses that resolved directory. Never drop or purge shared default storage.
The local test command is node --test --test-isolation=none test/core.test.js test/sdk.test.js after setting that launch environment and clearing cloud credentials/flags. The suite asserts the actual SDK storage client base. The launch environment takes precedence over constructor storageDir, so the roundtrip tests use distinct store/dataset IDs within the same verified isolated base. Local non-PPE storage tests do not prove a hosted fee; budget and event behavior is tested with the real pinned charging manager and a stubbed native charge endpoint.
The Dockerfile installs only lockfile production dependencies and runs as the Node user. Native build, hosted run, pricing registration, and publication require the separate release gate and are outside local implementation.