Conversation
Contributor
Differences in type declarationsWe detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:
New type declarationspackages/cli-kit/dist/public/node/store-attribution.d.ts/**
* Records the store a command acted on, so command analytics can be grouped by store.
*
* @param storeFqdn - The store's fully qualified domain name.
* @param validated - Whether the fqdn was confirmed against the platform, rather than taken from user input as-is.
* @param storeId - The store's numeric id as a string. Ignored when it isn't numeric.
*/
export declare function recordStoreFqdnMetadata(storeFqdn: string, validated: boolean, storeId?: string): Promise<void>;
Existing type declarationsWe found no diffs with existing type declarations |
amcaplan
force-pushed
the
record-shop-id
branch
2 times, most recently
from
September 14, 2026 18:03
556a31a to
2d8783b
Compare
Dev store creations can't be attributed to the CLI today. Both the CLI and the dev dashboard call the same Business Platform mutation, and the `store_creations` row it writes keeps no caller, so the only way to identify CLI-created dev stores is a regex on the shop signup request's user agent. Request `shopifyShopId` from the create mutation and record it, along with the store domain, as command metadata. Preview stores already do this, so move `recordStoreFqdnMetadata` into `organizations` and share it rather than duplicating the metadata shape in two packages. `store` already depends on `organizations`, so its own attribution module becomes a one-line re-export, matching the shims it already uses for `createDevStore` and `businessPlatformTokenRefreshHandler`. Recorded before polling, so a store that is created but never reaches COMPLETE is still attributed. Also take the helper's arguments as an options object. `validated` is a positional boolean at nine call sites, where `recordStoreFqdnMetadata(store, false)` gives a reader nothing to go on, and the optional id made argument order the only thing distinguishing the two. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Assisted-By: devx/47074c59-ea41-4708-aac2-7fccae638d6f
amcaplan
force-pushed
the
record-shop-id
branch
from
September 14, 2026 19:55
2d8783b to
5908568
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
WHY are these changes introduced?
Dev store creations can't be attributed to the CLI vs. the dev dashboard in our metrics. Both surfaces call the same Business Platform mutation, and the
store_creationsrow it writes keeps no caller — so there is nothing to group by, andshop_signup_requeststags both paths identically.Today the only way to identify CLI-created dev stores is a regex on the shop signup request's user agent, which works but breaks if the user agent format ever changes.
Context: #dev-platform thread.
WHAT is this pull request doing?
Request
shopifyShopIdfromcreateAppDevelopmentStoreand record it, with the store domain, as command metadata — giving the warehouse astore_idto join on instead of inferring the surface from a user agent.One note for anyone writing the query:
cli3_commandsalso has ashop_idcolumn, from monorail schemas 1.23 and 1.27, but no released CLI ever populated it — the field was added and withdrawn between 3.94.3 and 4.0.0, then renamed tostore_idin 1.28 before being adopted.store_idis the live field.Preview stores already record this, so
recordStoreFqdnMetadatamoves intoorganizationsand is shared rather than duplicating the metadata shape. The dependency already runsstore→organizations, so the helper moves down a layer instead of the call moving up, andpackages/store/src/cli/services/store/attribution.tsbecomes a one-line re-export — the same shim patternstorealready uses forcreateDevStoreandbusinessPlatformTokenRefreshHandler, which keeps every existing import site instoreunchanged.appreachescreateDevStorethrough the same barrel (app/src/cli/services/dev/select-store.ts:40), so one call site insidecreateDevStorecovers bothstore create devandapp dev's inline store creation.While moving it, the helper now takes an options object.
validatedwas a positional boolean at nine call sites —recordStoreFqdnMetadata(store, false)told a reader nothing, and with the optional id, argument order was the only thing separating the store domain from the store id. This is what puts thestorecall sites back in the diff; they're mechanical, and no behavior changes.Four decisions worth a reviewer's eye:
COMPLETE, and those are exactly the cases worth seeing during rollout. A poll timeout or failure still attributes.gid://shopify/Shop/123) — the resolver passes the same value asshopify_shop_gid— and the metadata field is numeric, so an un-normalized value would be silently dropped. Bare-numeric values pass through, matching the existingnumberFromGidhandling inapp-management-client.ts.organizations, not cli-kit. Onlystoreandorganizationsneed it today, and cli-kit's./*export would make it published public API. Promoting it later is cheap; demoting it isn't.validatedstayed required. Seven call sites passtrueand two passfalse, so neither default is safe: defaulting totruewould silently claim user-supplied input had been checked against the platform.This makes the CLI vs. dashboard split visible, but it is a floor rather than exact attribution: CLI analytics are opt-out and best-effort, so anything missing reads as a dashboard creation, and failed creations produce no shop id at all. Persisting a
sourceonstore_creationsinshop/worldis still the complete fix.No changeset — this is telemetry only, with no user-visible behavior change.
How to manually test your changes?
The store id and domain should appear in the command's analytics payload:
Look for
store_idandstore_domainin the reported metadata.shopify store create previewshould report the same fields as before.Checklist
🤖 Generated with Claude Code