Files
go-cart-actor/pkg/cart/MUTATIONS.md
T
mats 8bb0a7a786
Build and Publish / BuildAndDeployAmd64 (push) Failing after 4s
Build and Publish / BuildAndDeployArm64 (push) Failing after 7s
tests and mutation docs
2026-07-03 19:30:02 +02:00

5.8 KiB

pkg/cart — mutation inventory

Every mutation file under pkg/cart/mutation_*.go plus the slice of cart state it touches. The grouping is subjective ("Subscription lifecycle", "Discount surface", etc.) — used as a starting point for collapsing the file-per-mutation pattern flagged in agents.md. Move two related mutations into one file first; if the test surface stays smaller than the two-file version, the grouping is real.

File Concern State it READS State it WRITES
mutation_items.go (mutation_add_item.go and mutation_remove_item.go merged; tests stay in mutation_add_item_test.go + mutation_remove_item_test.go) Line item add/remove state.Items state.Items, state.UpdatedAt
mutation_change_quantity.go Line item quantity state.Items[idx] state.Items[idx], state.UpdatedAt
mutation_clear_cart.go Wholesale clear state.Items, state.Vouchers, state.UpdatedAt
mutation_set_user_id.go Ownership state.UserID, state.UpdatedAt
mutation_set_cart_type.go (+ test) Cart type state.Type, state.UpdatedAt
mutation_add_voucher.go Discount surface state.Vouchers state.Vouchers, state.LineTotals (re-eval), state.UpdatedAt
mutation_set_custom_fields.go (+ tests) Custom K/V state.CustomFields state.CustomFields, state.UpdatedAt
mutation_set_recovery_contact.go (+ tests) Recovery state.Recovery, state.UpdatedAt
mutation_subscription_added.go Subscription state.Items state.Subscriptions, state.UpdatedAt
mutation_upsert_subscriptiondetails.go Subscription details state.Subscriptions state.Subscriptions, state.UpdatedAt
mutation_remove_line_item_marking.go Markings state.Items[idx].Markings state.Items[idx].Markings, state.UpdatedAt
mutation_line_item_marking.go Markings apply state.Items[idx].Markings state.Items[idx].Markings, state.UpdatedAt

Delete-test quick check

For any proposed grouping (e.g. merge all marking* mutations into one file), ask: does deleting the merged file concentrate complexity, or just move lines? For markings — yes, the shared logic (cascade to pricing) makes the merge worthwhile. For voucher vs custom_fields — no, those read different state and have different error contracts; keep separate.

What is already merged

pkg/cart/mutation_items.go (added 2025-07) — AddItem and RemoveItem both touch state.Items and share the ErrPaymentInProgress, decodeExtra, and getOrgPrice helpers. Merge passed the delete-test checks: the receiver *CartMutationContext, same grain (*CartGrain), same mutation-registry dispatch. Both mutation_*_test.go files remain because they assert specific method behaviour, not generic package behaviour. Verified: go test -count=1 ./pkg/cart/... clean (voucher test which references ErrPaymentInProgress still green).

Table corrections when merging

When the two source rows collapsed into one, two corrections landed in the merge:

  • AddItem's old READS column listed state.Vouchers (for stacking). That clause was incorrect — voucher stacking is AddVoucher's concern, not AddItem's. The merge drops the clause because reading mutation_add_item.go confirms AddItem only reads state.Items. This is a documentation correction, not a behaviour change.
  • Both State it READS / WRITES columns originally had (both) annotations to remind that two distinct mutations were sharing the row. After collapse the row already says Line item add/remove, so the (both) markers are noise — dropped.

If a future merge lands, follow the same pattern: read the actual source to verify the row's claimed state surface, and prune label-noise before compressing two rows into one.

NOT to merge next

mutation_change_quantity.go looks like an obvious candidate for the next merge (same receiver, same grain, same state.Items write surface). It is not — quantity has a partial-line-drop arithmetic contract that add/remove do not:

  • AddItem always merges or appends; never sets quantity down.
  • RemoveItem always removes whole lines; never decrements quantity.
  • ChangeQuantity may drop a line entirely if quantity reaches 0.

If you merge ChangeQuantity first, doing the same delete-test check yields: deleting the merged file leaves the partial-line arithmetic logic stranded in Apply, which IS a real concentration (good). But the inverse: if AddItem later grows a "decrement" edge case, the merged file will balloon and a re-split becomes expensive. Either keep ChangeQuantity separate, OR merge all three with the merge scoped to a "line item lifecycle" package and the partial-line arithmetic under a clearly-named helper.

How this maps onto a refactor

  1. Pick a row with shared logic (markings, subscription details).
  2. Move related mutations + their tests into one file under pkg/cart/<concern>.go.
  3. Re-run go test ./pkg/cart/... — same assertions, smaller surface.
  4. Update this table to reflect the new file layout.