fix(api-catalog): resolve discriminator.mapping refs to #/$defs pointers (DEVX-548)#96
Merged
jpage-godaddy merged 3 commits intoJul 14, 2026
Conversation
…ers (DEVX-548)
The API catalog left external file paths inside OpenAPI `discriminator.mapping`
blocks (e.g. "./BasicChannel.yaml", "../payment-token/ApplePayPaymentToken.yaml").
Unlike `$ref` objects, mapping values are plain strings, so the dereferencer never
rewrote them — and `api describe` surfaced broken, unresolvable schema references
for polymorphic commerce types (Amount, Fee, FundingSource, Channel, PricingModel).
The referenced subschemas are already lifted into `$defs` via the same key
derivation, so rewrite each external mapping value to the matching `#/$defs/<key>`
pointer (only when the def exists, so a mapping is never pointed at a missing
schema). Also extend the unresolved-ref guard to treat external mapping values as
build-failing, same as an external `$ref`, so future drift is caught in CI.
- generator: add rewrite_discriminator_mappings, run it after lifting in
load_and_dereference; extend collect_unresolved_refs to scan mappings
- regenerate-equivalent: rewrite 52 mappings across channels, payment-requests,
payments, subscriptions, transactions catalogs
- tests: mapping rewrite + drift-guard unit tests
Note: two residual external references remain and are scoped as follow-ups:
GraphQL `schemaRef` ("./graphql/schema.graphql") in catalog-products/taxes
(tied to the GraphQL work in DEVX-546), and JSON-Schema `$id` URIs (valid
identifiers, not broken refs).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
node_modules/, dist/, .pnpm-store/, and .npmrc are artifacts of the legacy TS CLI and are not part of the Rust port. They surface as untracked noise when switching into the rust-port working tree; ignore them. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… (DEVX-548) Adds the negative-path test for the safety guard: a discriminator.mapping value whose target is never lifted into $defs is left external (not pointed at a missing key), and collect_unresolved_refs then flags it so the build fails. Locks in the `def_keys.contains` guard behavior. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jpage-godaddy
approved these changes
Jul 14, 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.
Problem
gddy api describereturned broken, unresolvable schema references for polymorphic commerce types (Amount,Fee,FundingSource,Channel,PricingModel,CallbackAuthentication).The API catalog resolves
$refobjects into local#/$defs/...entries, but OpenAPIdiscriminator.mappingcarries schema references as plain strings, not$refobjects — so the dereferencer never rewrote them. The generated catalog kept external file paths like:A developer inspecting a commerce schema via
api describegot a dead file path instead of a resolvable pointer. 52 such leaks existed acrosschannels,payment-requests,payments,subscriptions, andtransactions.Fix
rust/tools/generate-api-catalog): addedrewrite_discriminator_mappings, run after ref-lifting inload_and_dereference. It rewrites each external mapping value to the matching#/$defs/<key>using the same key derivation as$reflifting — and only when that def exists, so a mapping is never pointed at a missing schema.discriminator.mappingvalues as build-failing, exactly like an external$ref. Future spec drift now fails generation instead of silently shipping a broken pointer.Impact
gddy api describenow returns fully-resolvable schemas for all polymorphic commerce types.discriminator.mappingvalues (verified: 0 remaining leaks, 0 dangling#/$defspointers, all catalog files valid JSON).Scope / follow-ups
The original ticket cited 587 unresolved external
$refs — that was already fixed onrust-port; all 1787$refs now resolve internally. This change addresses the residual plain-string leaks. Two remaining external references are intentionally out of scope:schemaRef(./graphql/schema.graphql) incatalog-productsandtaxes— tracked with the GraphQL commerce work (DEVX-546).$idURIs — valid identifiers, not broken references; left as-is.Testing
cargo test -p generate-api-catalog— 10/10 pass (incl. 2 new)cargo test api_explorer— pass with rewritten catalogs embeddedcargo clippy -p generate-api-catalog -- -D warnings— cleancargo fmt --check— cleanNotes for reviewers
Includes a small unrelated chore commit gitignoring legacy TS build artifacts (
node_modules/,dist/,.pnpm-store/,.npmrc) that surface as untracked noise in the rust-port tree. Happy to split it out if preferred.