play products: clamp regional prices to Play's min/max, per-product results; apple iap: skip live localizations, per-product results

This commit is contained in:
CRTkafa 2026-10-23 16:52:28 +08:00
parent 882255a32f
commit b0641c1fc8
12 changed files with 456 additions and 69 deletions

View file

@ -1323,3 +1323,30 @@ that fails without the fix (see CONTRIBUTING.md).
- **Guard:** `cli/lib/ship-step.ts` holds the one exit-code mapping; `play upload` and `apple upload` check the store
before sending and stop with exit 7 (`tests/ship-step.test.ts`, fake stores); `--env-file` values are scrubbed from
every output.
## 111. `play products` died on a high price: "Price for KR must be between ₩70 and ₩600,000"
- **What happens:** the regional prices come from `convertRegionPrices` (a USD base converted per region). Play does
not check its own min / max there, so a 649.99 USD product converts to ₩950,000 in KR and the PATCH is refused 400.
The run used to stop at that product, after the earlier ones were already created and activated.
- **Do:** run `storebound play products --dry`: it names every region outside its min / max (`price limits on <id>:
KR KRW 942486 -> 600000`). The write clamps those regions to the bound with a warning; `--skip-out-of-range-regions`
leaves them out instead. A limit Play reports that storebound did not know is learned from the 400, saved in
`.storebound/play-price-limits.json` and the PATCH is sent again. Set an explicit `overrides` price if you want a
different price in that region.
- **Guard:** `cli/lib/play-limits.ts` (seed table, 400 parser, clamp); one product failing no longer stops the others:
every product gets a `result` line and the run exits 1 at the end. Play subscriptions (base plan and pay-up-front
offer regions) use the same clamp and keep going after a failed subscription. `tests/price-limits-locked-loc.test.ts`.
## 112. `apple iap` died on an approved product: "Cannot edit InAppPurchaseLocalization when it is in ACTIVE state"
- **What happens:** once an in-app purchase (or subscription, subscription group) is approved, its localizations are
live. PATCH answers 409 `ENTITY_ERROR.ATTRIBUTE.INVALID.UNMODIFIABLE`, and the run stopped there, before the price
schedule of that and the later products.
- **Do:** run `storebound apple iap --dry`: a changed name / description on an APPROVED / ACTIVE localization is
marked "not editable now (changes ship with the next review of the product / needs a new localization)". The write
skips those edits with a warning and still applies prices, attributes, availability and the other products. To change
the live text, edit it in the product's next review round (App Store Connect) or add a new localization.
- **Guard:** `cli/lib/loc-lock.ts` reads the localization `state` (IAP, subscription and group localizations) and treats
a 409 UNMODIFIABLE the same way; one IAP failing no longer stops the others (results at the end, exit 1).
`tests/price-limits-locked-loc.test.ts` (fake ASC answers the 409 for APPROVED / ACTIVE localizations).