price changes of existing products need --allow-price-changes (play products, play/apple subscriptions, prices import): --yes and flow run --apply --yes confirm creates, first prices and other updates only; without the flag the run writes the rest, names each held change and exits 3 (declined), dry runs mark them owner, flows refuse the flag; lib/price-gate.ts, tests/price-gate.test.ts. CLI wording: console fill leaves what it cannot open or fill to the calling agent's browser tool (console plan / verify) instead of 'yourself'; other 'by hand' output points at the config; do-it-dont-ask test scans cli/ output
This commit is contained in:
parent
b5b8f2da9d
commit
e01a27d7b7
33 changed files with 414 additions and 117 deletions
|
|
@ -50,7 +50,7 @@ every one of `fastlane/`, `ios/fastlane/`, `android/fastlane/` that exists; pass
|
|||
- `price_tier`: products and the prices CSV (`store-iap-setup`). Age rating config: `store-declarations`.
|
||||
Export compliance: `export-compliance` (`apple.usesNonExemptEncryption` stays commented out).
|
||||
- Lanes, `match`, `gym` / `gradle`: building and signing stay where they are; storebound has no lanes.
|
||||
- Ruby logic (`for_platform`, `for_lane`, `ENV[...]`, interpolation): reported by key and line, set by hand.
|
||||
- Ruby logic (`for_platform`, `for_lane`, `ENV[...]`, interpolation): reported by key and line; set those in storebound.config.ts.
|
||||
- Promo graphic, TV banner, TV / Wear screenshots, Apple TV privacy policy, Korean trade representative contact:
|
||||
consoles.
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ Config (optional): `prices: { ppp: { source, file, floor, ceiling, out } }`.
|
|||
`storebound prices ppp` (default `store/prices-ppp.csv`, `--out` to change it).
|
||||
4. The owner reviews and edits the CSV (delete rows to keep a store's own conversion, round to a house price ladder).
|
||||
5. Apply through the normal price sheet flow: `storebound prices import --csv store/prices-ppp.csv --dry`, then
|
||||
without `--dry` in a terminal after the owner says yes (see store-iap-setup). Import checks Apple price points
|
||||
`--yes --allow-price-changes` after the owner says yes to that diff (see store-iap-setup; `--yes` alone never
|
||||
changes an existing price). Import checks Apple price points
|
||||
(the error lists the neighbours) and Play's region currencies.
|
||||
|
||||
## Read before applying
|
||||
|
|
|
|||
|
|
@ -49,8 +49,11 @@ once (the second build step prints "prebuild skipped (already ran in this flow r
|
|||
- `--apply`: writes and shell steps run for real; each write command still asks its own confirmation in the
|
||||
terminal. Never add `--yes` to a step (flow validate refuses it).
|
||||
- `--apply --yes`: how you run it after showing the dry run (do it, don't ask: AGENTS.md first rule): every write
|
||||
step gets `--yes`; reads, waits and owner steps do not, so nothing owner-only runs. When the dry run shows a live price change
|
||||
(`play products`, `apple subscriptions` on an existing product), get the owner's yes for it first. Without `--yes` and without a terminal, a confirming command declines: the flow stops there with
|
||||
step gets `--yes`; reads, waits and owner steps do not, so nothing owner-only runs. `--yes` never changes the price
|
||||
of an existing product (`play products`, `apple subscriptions`, `play subscriptions`): such a step writes everything
|
||||
else, names each held change ("price change on <id> (<from> -> <to>) needs the owner") and exits 3, so the flow
|
||||
stops as declined. After the owner's yes for that diff, run that one command with `--allow-price-changes` (refused
|
||||
in flow steps, never added by `flow run`), then `flow run <name> --apply --yes --resume`. Without `--yes` and without a terminal, a confirming command declines: the flow stops there with
|
||||
"step N declined: not a terminal and no --yes ...", never "ok" (status `declined` in `--json` and the state file).
|
||||
- Owner steps never run in any mode: submit, release, phased release, rollout, sending review replies, price
|
||||
imports, inviting testers, Beta App Review, starting experiments, offer codes (AGENTS.md rule 1). They print as
|
||||
|
|
|
|||
|
|
@ -30,10 +30,13 @@ Auto-renewable subscriptions are a separate list (`subscriptions`, `store-subscr
|
|||
2. `storebound play products`. Per product: `pricing:convertRegionPrices` (USD -> every region at local price points,
|
||||
and the `regionsVersion`), your overrides on top, `PATCH .../onetimeproducts/{id}?allowMissing=true®ionsVersion.version=...`
|
||||
(create or update), then `oneTimeProducts/{id}/purchaseOptions:batchUpdateStates` to activate (new options are DRAFT).
|
||||
New products and listing text go straight through. Price, region or activation changes of an EXISTING product
|
||||
are the owner's decision: the run shows the diff and asks in a terminal; without a terminal (MCP, CI, the desktop
|
||||
app's normal write) they are skipped with a warning, the listing text still updates. The owner confirms in a
|
||||
terminal, or applies prices with the desktop Prices "Apply" (owner action, `prices import`).
|
||||
New products (with their first prices) and listing text go straight through; `--yes` confirms activating the
|
||||
purchase option of an existing product. Price or region changes of an EXISTING product are the owner's decision
|
||||
and `--yes` never confirms them (also not the `--yes` that `flow run --apply --yes` adds): the dry run marks those
|
||||
rows `owner`, and a real run writes everything else, prints `price change on <id> (<from> -> <to>) needs the
|
||||
owner: re-run with --allow-price-changes` and exits 3 (declined; a flow stops there). After the owner's yes in
|
||||
chat for exactly that diff, run `storebound play products --allow-price-changes`; the owner can also answer the
|
||||
question in a terminal (no `--yes`) or use the desktop Prices "Apply" (owner action).
|
||||
3. Verify: `storebound play status` lists every product with `buy:ACTIVE`.
|
||||
4. Test: Play Console > Settings > License testing: add tester Gmail accounts; install from the internal testing
|
||||
link; purchases are free test orders.
|
||||
|
|
@ -41,7 +44,8 @@ Auto-renewable subscriptions are a separate list (`subscriptions`, `store-subscr
|
|||
## App Store (API + UI)
|
||||
1. `storebound apple iap --dry`, then `storebound apple iap`: creates missing products, localizations, a price schedule
|
||||
(USA base + overrides; Apple equalizes the rest) and availability. Existing schedules and availability are never
|
||||
changed by it; price changes go through `storebound prices import` (diff first, then the owner confirms).
|
||||
changed by it; price changes go through `storebound prices import` (diff first, then the owner's yes and
|
||||
`--allow-price-changes`).
|
||||
2. Review screenshot per product (a real device size, e.g. 1290 x 2796, showing the item in the shop):
|
||||
`storebound apple iap-review`. States move to READY_TO_SUBMIT when complete.
|
||||
3. **Send them to App Review** (the owner's step): `storebound apple iap-submit --dry` shows the plan: which version
|
||||
|
|
@ -74,7 +78,9 @@ App Store only, a future YYYY-MM-DD).
|
|||
neighbours); Play takes any price in the region's currency.
|
||||
3. `storebound prices import --dry` (MCP: `prices_diff`) prints the diff table: product, store, region, from, current,
|
||||
new, change %. Show it to the owner.
|
||||
4. The owner runs `storebound prices import` (asks first; not an MCP tool). Apple: one new price schedule per changed
|
||||
4. After the owner's yes for that diff: `storebound prices import --yes --allow-price-changes` (not an MCP tool;
|
||||
`--yes` alone only sets first prices of products that have none and exits 3 naming every held price change).
|
||||
Apple: one new price schedule per changed
|
||||
product (base territory, default the current one or `prices.baseTerritory`, plus every manual price; territories
|
||||
without one follow Apple's equalization). Play: the purchase option's regional prices are replaced; regions the
|
||||
product has no price for get `convertRegionPrices` from the USD base, `--reconvert` resets every region the CSV
|
||||
|
|
|
|||
|
|
@ -34,8 +34,10 @@ offers, offerCodes, reviewScreenshot, basePlanId, gracePeriod, platforms }] }]`,
|
|||
billing library on a track.
|
||||
2. `storebound check` (limits: Apple name 30 / description 45; Play description 200, up to 4 benefits).
|
||||
3. `storebound apple subscriptions --dry` and `storebound play subscriptions --dry`; show the plan, then run them
|
||||
yourself (`--yes`). A price change of an existing subscription is a live price: get the owner's yes for it first.
|
||||
Through MCP (no terminal) they only create what is new; price changes of existing subscriptions wait for the owner.
|
||||
yourself (`--yes`): new subscriptions, first prices, listings, base plans and offers are written. A price change
|
||||
of an existing subscription is a live price and `--yes` never applies it: the run writes everything else, prints
|
||||
`price change on <id> (<from> -> <to>) needs the owner: re-run with --allow-price-changes` and exits 3. After the
|
||||
owner's yes in chat for that diff, run it again with `--yes --allow-price-changes`. Flows never pass that flag.
|
||||
4. Review screenshot of the paywall per subscription (`reviewScreenshot`), uploaded by `apple subscriptions`.
|
||||
5. **First subscriptions go with an app version** (and a new group with at least one of its subscriptions):
|
||||
`storebound apple iap-submit --with-version --dry` plans one review submission with the app version, the
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue