fix: stop querying attribute fields removed in 3.24 - #6871
Merged
Conversation
The shared attribute fragments still selected `availableInGrid`, `filterableInStorefront` and `storefrontSearchPosition`. 3.24 removes them from `Attribute`, so attribute list, details and update all failed validation against the staging schema. The previous deprecation gated every reader behind `isMainSchema()` but left the selections in, on the assumption the fields would stay `@deprecated` on staging rather than disappear. They disappeared. Shared fragments are now schema-agnostic — nothing outside `src/attributes/` ever read those three fields, which keeps products, product types, model types and customers out of the split. The fields moved to a main-only `AttributeFacetedNavigation` fragment spread by the five documents that render them, each with a 3.24 twin that omits it: - `queries.staging.ts`: AttributeDetails, AttributeList, PageTypeAssignedAttributesForList, ProductTypeAssignedAttributesForList - `mutations.staging.ts`: AttributeUpdate `schemaAwareOperations.ts` picks the document per build flag. Results stay typed after the main variant, a superset, which is safe because the readers are already gated. AttributeCreate needs no twin: it only selects `id`. Under 3.23 the faceted navigation settings, the "Use in faceted search" column and its sorting all behave exactly as before. Two latent crashes on 3.24 are fixed on the way: `attributePageForm` called `.toString()` on the now-absent `storefrontSearchPosition`, and a bookmarked "Use in faceted search" sort URL sent an enum value 3.24 no longer defines. codegen-staging and graphql.config now also load `./src/fragments/*.ts` so the twins resolve shared fragments, which doubles as a drift guard: every shared fragment is validated against 3.24. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Replaces the hand-maintained 3.24 twins of the attribute documents with a
directive the client resolves at build time. Fields that exist in only one
schema version are marked in place:
availableInGrid @lockSchema(schema: "main")
and are stripped from the document when the build targets the other version.
One source document, no twin to drift.
Stripping happens on the cache, not in a link. Links run after the cache, so a
link-level transform leaves InMemoryCache normalising against fields the API was
never asked for: every write logs "Missing field ...", every cache-first read
misses, and the query refetches on every mount. `transformDocument` feeds both
the cache and the link, so the two stay in sync. Apollo Client 3.8 has a
first-class `documentTransform` for this; the subclass goes away when we get
there.
Two passes over the document, because `removeDirectivesFromDocument` derives
`shouldRemoveField` from `directives.some(d => d.remove)` — a document-wide flag
rather than a per-config one. A single call carrying both configs deletes every
`@lockSchema` field, not just the locked-out ones.
`AttributeFacetedNavigation` keeps an unconditional `id`. A fragment whose every
field is stripped prints as an empty selection set, which `graphql.validate`
accepts and the API rejects as a syntax error; `lockSchema.test.ts` re-parses
after printing so that can't slip through again. The test resolves the five real
generated documents for both versions and validates them against schema-main and
schema-staging loaded without the directive declaration, so a surviving
`@lockSchema` fails as an unknown directive exactly as the API would.
Behaviour is unchanged on both schemas: readers of the three fields stay gated
behind `isMainSchema()` and the types remain a superset.
Deleted: queries.staging.ts, mutations.staging.ts, schemaAwareOperations.ts and
its test. Call sites are back on the generated hooks.
Not covered: `cache.readQuery`/`writeQuery` reach `read`/`write` directly and
bypass `transformDocument`. No caller does that with a `@lockSchema` document
today, and the gap is marked where the override would go.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: a37b122 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #6871 +/- ##
=========================================
Coverage 56.78% 56.78%
=========================================
Files 3542 3542
Lines 73484 73488 +4
Branches 18646 19030 +384
=========================================
+ Hits 41725 41728 +3
+ Misses 31077 29813 -1264
- Partials 682 1947 +1265
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Folds `AttributeFacetedNavigation` back into the shared fragments. The separate fragment existed so the 3.24 twin documents could omit one spread; with the twins gone and `@lockSchema` resolving per build, it only bought indirection. The three fields return to exactly where they sat before any of this: `filterableInStorefront` on `Attribute`, `availableInGrid` and `storefrontSearchPosition` on `AttributeUpdateResult` and `AttributeDetails`. That placement matches the readers — the list datagrid reads `filterableInStorefront` off a row, `attributePageForm` reads all three off the details query — and is narrower than putting all three on `Attribute`, which this first did and which eight fixture type errors caught. Gone with it: `src/attributes/types.ts`, whose `Partial<>` wrappers only existed because the twins disagreed about which fields a row carried, and the `id` placeholder that kept the fragment from collapsing into an empty selection set. Resolution is now a plain `graphql` visitor. Apollo's `removeDirectivesFromDocument` throws on the multi-fragment document files codegen hands it, and its document-wide `remove` flag meant it could not keep and drop `@lockSchema` fields in one pass. The staging codegen no longer loads `./src/fragments/*.ts`. `documentTransforms` do run ahead of validation, but the import-types preset never forwards them, so hooksStaging validated the unresolved documents and failed. lockSchema.test.ts guards this instead, and guards it better: it sweeps all 445 generated documents, resolves `@lockSchema` for both versions, re-parses and validates against the real schemas loaded without the directive declaration. That covers the whole app rather than the attribute module, and would have caught the original 3.24 breakage. That sweep found one unrelated pre-existing break: ExportGiftCards still selects `exportGiftCards` and `ExportGiftCardsInput`, both removed in 3.24. Listed in KNOWN_324_GAPS so it is visible rather than silent; not fixed here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`exportGiftCards` is deprecated in 3.23 and removed from `Mutation` in 3.24, but nothing gated the UI. On a 3.24 build the menu item rendered, the dialog opened, and the failure only landed when the user pressed Export — on a request the API rejects as invalid. Gated at all three entry points behind `isMainSchema()`, matching how the attribute module handles its removed fields: - the "Export codes" item in the gift card list menu - the "Export to email" button in the bulk-create success dialog - the dialog render in GiftCardListDialogsProvider The last one is not redundant. The dialog renders off `params.action === EXPORT`, so a bookmarked ?action=EXPORT URL would still reach it with the menu item gone — the same hole this branch already closed for the attribute sort field. Gating sits at the render sites rather than inside GiftCardExportDialogContent, which calls `useExportGiftCardsMutation` and `useGiftCardTotalCountQuery` up front and cannot return early without breaking hook order. ExportGiftCards stays in KNOWN_324_GAPS: this removes the document's reachability, not the document, so codegen still emits it and lockSchema.test.ts still sees it. The comment there now records why `@lockSchema` cannot cover this case at all — the mutation is the operation's only root field, so stripping it leaves an empty selection set, and `$input: ExportGiftCardsInput!` is a variable definition the directive cannot reach. playwright/tests/giftCards.spec.ts clicks `exportCodesMenuItem` in two tests. On 3.23 they are unaffected; on a 3.24 run they now fail at the click rather than at the mutation. The Playwright suite is not schema-aware, so it is left as is. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The field form cannot express a mutation that disappears entirely: deleting the only root field leaves an empty selection set, and a variable definition naming a removed input type is out of the directive's reach. So `ExportGiftCards` sat in a hardcoded `KNOWN_324_GAPS` list in the sweep test instead. An operation-level lock is a build-time marker — nothing is stripped at runtime, entry-point gating still does that — but it lets the gap be declared next to the mutation, and the sweep read it instead of a name list. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`exportGiftCards` is gone from the 3.24 API and deprecated on 3.23, where it stays reachable directly through the API. Rather than keep the UI alive behind a schema check, the export dialog and its entry points are removed. The bulk-issue success dialog goes with them — offering to email the codes was its only action, so the success notification is now the only confirmation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…chema-attribute-fields
lkostrowski
marked this pull request as ready for review
August 27, 2026 06:25
lkostrowski
enabled auto-merge (squash)
August 27, 2026 06:25
mirekm
approved these changes
Aug 27, 2026
This was referenced Aug 27, 2026
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.
The shared attribute fragments still selected
availableInGrid,filterableInStorefrontandstorefrontSearchPosition. 3.24 removes them fromAttribute, so attribute list, details and update all failed validation againstthe staging schema.
The previous deprecation gated every reader behind
isMainSchema()but left theselections in, on the assumption the fields would stay
@deprecatedon stagingrather than disappear. They disappeared.
Shared fragments are now schema-agnostic — nothing outside
src/attributes/ever read those three fields, which keeps products, product types, model types
and customers out of the split. The fields moved to a main-only
AttributeFacetedNavigationfragment spread by the five documents that renderthem, each with a 3.24 twin that omits it:
queries.staging.ts: AttributeDetails, AttributeList,PageTypeAssignedAttributesForList, ProductTypeAssignedAttributesForList
mutations.staging.ts: AttributeUpdateschemaAwareOperations.tspicks the document per build flag. Results stay typedafter the main variant, a superset, which is safe because the readers are
already gated. AttributeCreate needs no twin: it only selects
id.Under 3.23 the faceted navigation settings, the "Use in faceted search" column
and its sorting all behave exactly as before.
Two latent crashes on 3.24 are fixed on the way:
attributePageFormcalled.toString()on the now-absentstorefrontSearchPosition, and a bookmarked"Use in faceted search" sort URL sent an enum value 3.24 no longer defines.
codegen-staging and graphql.config now also load
./src/fragments/*.tsso thetwins resolve shared fragments, which doubles as a drift guard: every shared
fragment is validated against 3.24.
Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com## Scope of the change