fix: keep order/cart address copies live until frozen - #196
Merged
sveneberth merged 3 commits intoJul 31, 2026
Merged
Conversation
`OrderSkel.billing_address` and `CartNodeSkel.shipping_address` used `updateLevel=OnValueAssignment` to persist the address as a copy, but that froze the copy already at assignment time: edits made to the referenced address during an ongoing checkout (adding a birthdate in a later step, correcting the address) were never mirrored onto the order/cart, and `OnValueAssignment` additionally turned the existing `refresh_*` helpers into no-ops. Add `SnapshotRelationalBone`, which keeps the copy in sync (like `Always`) while the owning skeleton is editable and freezes it via a `refresh()` no-op once the skeleton is frozen (`is_ordered` for the order, `is_frozen` for the cart). This preserves the snapshot for completed orders while reflecting live edits until checkout completes. Also guard `refresh_shipping_address` against sub-node skeletons that don't carry the `shipping_address` bone.
phorward
requested changes
Jul 29, 2026
Co-authored-by: Jan Max Meyer <jmm@phorward.de>
phorward
approved these changes
Jul 31, 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.
Summary
OrderSkel.billing_addressandCartNodeSkel.shipping_addresspersist the referenced address as a copy (refKeys="*"). Since #179 they useupdateLevel=OnValueAssignment, which freezes that copy already at assignment time — so any edit to the address during an ongoing checkout (adding abirthdatein a later step, correcting the address) was never mirrored onto the order/cart.OnValueAssignmentadditionally turned the existingrefresh_billing_address/refresh_shipping_addresshelpers into silent no-ops.Fix
New
SnapshotRelationalBone:updateLevel=Always, so the copy is kept in sync — both by theupdate_relationstask (target edited) and by explicitrefresh()calls — while the owning skeleton is still editable;refresh()to a no-op once the owning skeleton is frozen, preserving the snapshot captured at freeze time.The freeze predicate is configurable:
is_orderedforOrderSkel.billing_address, and the defaultis_frozenforCartNodeSkel.shipping_address.Also guards
refresh_shipping_addressagainst sub-node skeletons that don't carry theshipping_addressbone (previously raisedAttributeErroron every cart read of such a node).Trade-off
While a skeleton is frozen, editing a referenced address still triggers the
update_relationstask (the relation is serialized asAlways) and re-writes the referencing order/cart once — butrefresh()is a no-op there, so the persisted snapshot stays unchanged. Avoiding that extra write would require a dynamic serializedupdateLevel, which is out of scope here.Test plan
updateLevelis forced toAlways;refresh()runs while open and no-ops while frozen (bothis_orderedandis_frozenpredicates).birthdateadded in a later step now propagates to the still-open order, and a frozen/completed order is no longer changed by later address edits.