Repository navigation
fix(api-sync): make --apply idempotent per (class, field/enum value) - #39
Merged
Merged
Conversation
… enum value) reconcileTypes()/reconcileEnums() computed missing fields/enum cases per schema, not per underlying SDK class. A multi-schema spec-map.json entry (e.g. spec: ["PayinOut", "CreatePayinOut"] sharing one class) or two separate entries mapping the same class (TrackingTransaction reused across the payin and payout tracking_transaction paths; LimitIncreaseRequestSupportingDocumentType mapped from two different schemas) could independently report the exact same missing (class, field) or (class, value) gap once per schema/entry that lacked it. --apply then inserted the same promoted property/ fromArray line/toArray line, or the same enum case, twice into one file in a single run -- corrupting the source with duplicate constructor parameters on the first real multi-schema drift. Fixes it by deduplicating at the point applicable changes are generated: a $scheduledInsertions index in reconcileTypes() (keyed by class|field) and a $scheduledCases index in reconcileEnums() (keyed by class|value) make each function emit at most one applicable change per (class, field-or-value) per run, regardless of how many schemas or map entries independently found it missing. A second --apply run over already-patched source is byte-identical (verified via the existing determinism proof). Adds three regression tests reproducing the exact double-apply: a multi-schema single entry, two separate entries mapping the same class, and the enum-side equivalent. All three fail (2 applicable instead of 1) against the pre-fix code and pass after. No version bump -- pure tooling correctness fix. Claude-Session: https://claude.ai/code/session_01F1stiNzuNtJXoXtiW9ZCbs
Contributor
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
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.
Summary
reconcileTypes()andreconcileEnums()computed missing fields/enum cases perschema (or per map entry), not per underlying SDK class. A multi-schema
spec-map.jsonentry sharing one class (e.g.spec: ["PayinOut", "CreatePayinOut"]both pointing at
PayinTrackingPayment), or two separate entries mapping the sameclass (
TrackingTransactionreused across the payin and payouttracking_transactionpaths, or
LimitIncreaseRequestSupportingDocumentTypemapped from two differentschemas), could independently report the exact same missing
(class, field)or(class, value)gap once per schema/entry that lacked it.--applythen inserted the same promoted constructor property /fromArrayline /toArrayline, or the same enum case, twice into one file in a single run --corrupting the source with duplicate constructor parameters. Hit this for real while
wiring up the new coverage checks in feat(api-sync): enum and nested-object coverage checks, delivery manifest verification #38 (had to revert and apply those fields by
hand instead of trusting
--apply).$scheduledInsertions(keyedclass|field) inreconcileTypes()and$scheduledCases(keyedclass|value) inreconcileEnums().Each function now emits at most one applicable change per
(class, field-or-value)per run, regardless of how many schemas or map entries independently found it
missing. A second
--applyover already-patched source is byte-identical (verifiedvia the existing determinism-proof pattern, run locally against the real repo).
Regression tests
Three new tests in
tests/ApiSync/ApiSyncTest.php, each reproducing one trigger shapeof the exact bug and verified to fail (2 applicable entries instead of 1) against the
pre-fix code, pass after:
a_multi_schema_entry_missing_the_same_field_on_both_schemas_is_only_scheduled_oncetwo_separate_entries_mapping_the_same_class_missing_the_same_field_are_only_scheduled_oncetwo_enum_entries_mapping_the_same_class_missing_the_same_value_are_only_scheduled_onceEach also applies the (deduped) change and asserts the field/case appears in the
patched file exactly once, then re-runs reconciliation to confirm nothing is left
pending.
No version bump
Pure tooling correctness fix, not a change to the published SDK's public surface.
Test plan
composer run test-- 121 passed (118 pre-existing + 3 new), 743 assertionsgit stashonscripts/api-sync.phponly)and pass post-fix
composer run lint:check-- cleanphp scripts/api-sync.php --checkagainst the real repo's spec-snapshot -- exit 0byte-identical) -- OK
php scripts/contract-check.php-- OKhttps://claude.ai/code/session_01F1stiNzuNtJXoXtiW9ZCbs