Add production preview store create command#7764
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
a95b7a4 to
897e9ea
Compare
e6b9771 to
f0160e7
Compare
72f8f19 to
b504c98
Compare
b504c98 to
c3f7626
Compare
| const acquiredAt = dependencies.now().toISOString() | ||
| const userId = previewUserId(response) | ||
|
|
||
| await dependencies.recordStoreFqdnMetadata(response.shop.domain, false) |
There was a problem hiding this comment.
🐛 Bug: Two concerns at this call site, both pointing at the same fix:
-
Ordering risk: Both
recordStoreFqdnMetadatacalls precedesetStoredStoreAppSession. The testdoes not persist a store session when recording store metadata failslocks this in, but at that point the backend has already created the preview store and issued an admin token — if metadata throws (e.g., 'bubble' contexts), the token is dropped and the merchant is left with an orphaned store and no local credential. Metadata is best-effort observability; it should not gate token persistence. -
Redundant pair of calls: In
auth/index.tsthevalidated:false→validated:truetransition straddles the OAuth handshake, so both states are meaningful. Here the two calls fire back-to-back with no intervening validation step, andrecordStoreFqdnMetadataObject.assigns into a shared bag — so thefalsewrite is immediately overwritten bytrueand adds no telemetry signal.
Suggestion: Persist the session first, then record metadata once with true:
| await dependencies.recordStoreFqdnMetadata(response.shop.domain, false) | |
| dependencies.setStoredStoreAppSession({ | |
| store: response.shop.domain, | |
| clientId: STORE_AUTH_APP_CLIENT_ID, | |
| userId, | |
| accessToken: response.adminApiToken, | |
| scopes: [], | |
| acquiredAt, | |
| kind: 'preview', | |
| preview: { | |
| shopId: response.shop.id, | |
| name: response.shop.name, | |
| createdAt: acquiredAt, | |
| ...(response.placeholderAccountUuid ? {placeholderAccountUuid: response.placeholderAccountUuid} : {}), | |
| ...(country ? {country} : {}), | |
| }, | |
| }) | |
| dependencies.setLastSeenUserId(userId) | |
| await dependencies.recordStoreFqdnMetadata(response.shop.domain, true) |

WHY are these changes introduced?
This productionizes
shopify store create previewon top of the shipped preview-store backend endpoint so an agent can create a preview store and immediately use the returned Admin API token through existing store command auth plumbing.The command now targets the production endpoint contract from shop/world:
POST /services/preview-storesnameand explicitcountry_codeshopdetails andadmin_api_tokenWHAT is this pull request doing?
shopify store create previewwith flags:--name--countrywith two-letter code validation--json--no-color/--verbosehttps://<app-management-fqdn>/services/preview-storeswithout Basic auth or Identity auth.X-Shopify-CLI-Instancefrom a stable locally persisted install idX-Shopify-CLI-VersionUser-Agentshop.idshop.nameshop.domainplaceholder_account_uuidwhen presentadmin_api_tokenkind: 'preview', so the store is immediately usable byshopify store execute --store <domain>withoutshopify store auth.Notes / open questions
422 preview_store_create_failedpath and the currently observed backend500 preview_store_create_failedpath defensively.How to test your changes?
Ideally, the endpoint will be ready in prod to test this (protected behind a flag) and we can test as follows:
pnpm shopify store create previewPost-release steps
None.
Checklist
LocalStorage; command logic is platform-neutral.@shopify/cliand@shopify/store.